Home > database >  ReactJs - Sort method
ReactJs - Sort method

Time:02-13

I have a table in my react app and it gets its data from API.

I want to sort one of its columns. a[obj1][obj2] or b[obj1][obj2] Usually is a string of numbers and sometimes are equal to "-" (Dash) this is my sort function:

if (order === "DEF") {
  const sorted = props.currency.sort((a, b) =>
    Number(a[obj1][obj2]) > Number(b[obj1][obj2])
      ? 1
      : Number(b[obj1][obj2]) > Number(a[obj1][obj2]) || a[obj1][obj2] === "-"
      ? -1
      : 0
  );
  props.setCurrency(sorted);
  setOrder("ASC");
} else if (order === "ASC") {
  const sorted = props.currency.sort((a, b) =>
    Number(a[obj1][obj2]) < Number(b[obj1][obj2]) || a[obj1][obj2] === "-"
      ? 1
      : Number(b[obj1][obj2]) < Number(a[obj1][obj2])
      ? -1
      : 0
  );
  props.setCurrency(sorted);
  setOrder("DSC");
} else {
  const sorted = defaultCurrency;
  props.setCurrency(sorted);
  setOrder("DEF");
}

After the sort is called I want to behave with "-" like a zero, but the items which are equal to "-"are always placed on the top of the table when the order is equal to ASC or DSC, while the other items of the array are sorted correctly.

CodePudding user response:

If you want to behave with "-" like a zero then in the sort function you can add this as your first condition and return 0.

.sort((a, b) => {
    if (a[obj1][obj2] === "-") return 0;
    return Number(a[obj1][obj2]) > Number(b[obj1][obj2]) ? 1
     : Number(b[obj1][obj2]) > Number(a[obj1][obj2]) ? -1 : 0
})

CodePudding user response:

You can simplify this significantly by parsing the compared elements first, and then applying simple logic for the sorting.

Here declaring a single customSort which accepts an array, a function for retreiving the relevant property from each element, and a direction boolean which defaults to ascending: true.

The value of each element is then accessed using the passed function and converted to a number (here with unary ).

Finally the elements are sorted first by whether either isNaN otherwise by subrtracting based on the direction boolean.

const customSort = (arr, prop, asc = true) => {
  return [...arr].sort((a, b) => {
    a =  prop(a);
    b =  prop(b);

    return isNaN(a) - isNaN(b) || (asc ? a - b : b - a);
  })
}

const data = [{ prop1: { prop2: '2' } }, { prop1: { prop2: '5' } }, { prop1: { prop2: '3' } }, { prop1: { prop2: '1' } }, { prop1: { prop2: '-' } }, { prop1: { prop2: '9' } }, { prop1: { prop2: '-' } },];
const obj1 = 'prop1';
const obj2 = 'prop2';

console.log(customSort(data, (o) => o[obj1][obj2], true));
console.log(customSort(data, (o) => o[obj1][obj2], false));

  • Related