Search code examples
reactjsmaterial-table

Sorting numbers cast as strings in react


Background

My data contains strings like "1,000" and "123,000" and I want to sort them in a material-table. I want them to be sorted by the value from a number perspective not a string perspective.

Question

How do I sort cells by their numeric value not their string alphabetical order when I still want the cells to contain the commas that string formatting allows.

Code so far

I am trying to make salary sorting work here:

function CustomFilteringAlgorithm() {
  return (
    <MaterialTable
      title="Custom Filtering Algorithm Preview"
      columns={[
        {
          title: 'Name', 
          field: 'name',
          customSort: (a, b) => a.name.length - b.name.length
        },
        { title: 'Surname', field: 'surname' },
        { title: 'Birth Year', field: 'birthYear', type: 'numeric' },
        { title: 'Salary', field: 'salary', type: 'numeric',
          customSort: (a, b) => parseInt(a.salary) - parseInt(b.salary),
        },
        {
          title: 'Birth Place',
          field: 'birthCity',
          lookup: { 34: 'İstanbul', 63: 'Şanlıurfa' },
        },
      ]}
      data={[
        { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63, salary: '123,000' },
        { name: 'Joe', surname: 'Baran', birthYear: 1947, birthCity: 63, salary: '1,000' },
        { name: 'John', surname: 'Smith', birthYear: 1988, birthCity: 63, salary: '2,000' },
        { name: 'Jaun', surname: 'Smittle', birthYear: 1988, birthCity: 63, salary: '4,000' },
        { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34, salary: '45,000' },
        { name: 'Vishal', surname: 'Miller', birthYear: 2000, birthCity: 34, salary: '15,000,000' },
      ]}
      options={{
        sorting: true
      }}
    />
  )
}

Note

One can use the custom sort section on this page to test the code:


Solution

  • parseInt() won't work on strings with commas in them, you'll have to remove them manually when you sort:

    customSort: (a, b) => parseInt(a.salary.replace(/,/g, '')) - parseInt(b.salary.replace(/,/g, ''))