Home > Software engineering >  JS Array sort with multiple conditions by dynamically changing the order
JS Array sort with multiple conditions by dynamically changing the order

Time:08-03

I have an array of objects that I want to sort out by multiple conditions, And I had success doing that by running the following:

const data = [
  { age: 22, status: true, group: 1 },
  { age: 19, status: true, group: 1 },
  { age: 30, status: false, group: 2 },
  { age: 12, status: true, group: 1 },
  { age: 23, status: false, group: 2 },
  { age: 10, status: false, group: 2 },
]

const sorter = (data) => {
   return data.sort((a, b) =>
      Number(a.status) - Number(a.status) ||
      b.age - a.age ||
      b.group - a.group,

  )
}

console.log(sorter(data))

However, this always sorts by status then by age then by group because that's the order of the conditions, I want the order of the sort condidtions to be dynamic, for example sorter(data, ['group', 'status', 'age']) which will change the order of the sort conditions as in the passed array. Any help? Thanks!

CodePudding user response:

You can use properties dynamically. So mimic the same logic with a loop and dynamic property access:

const data = [
  { age: 22, status: true, group: 1 },
  { age: 19, status: true, group: 1 },
  { age: 30, status: false, group: 2 },
  { age: 12, status: true, group: 1 },
  { age: 23, status: false, group: 2 },
  { age: 10, status: false, group: 2 },
]

const sorter = (data, props) => {
   return data.sort((a, b) => {
      for (const prop of props) {
          const diff = Number(b[prop]) - Number(a[prop]);
          if (diff) return diff;
      }
      return 0;
  })
}

console.log(sorter(data, ['group', 'status', 'age']))

CodePudding user response:

you could do this dynamically like this

const data = [
{ age: 22, status: true, group: 1 },
{ age: 19, status: true, group: 1 },
{ age: 30, status: false, group: 2 },
{ age: 12, status: true, group: 1 },
{ age: 23, status: false, group: 2 },
{ age: 10, status: false, group: 2 },
];

const sorter = (data, fields) => {
   return data.sort((a, b) => {
   let value = false;
     for (let i = 0; i < fields.length; i  ) {
     value = value || Number(b[fields[i]]) - Number(a[fields[i]]);
     if (value) break;
   }
  return value;
  });
};

console.log(sorter(data, ["age", "group", "status"]));

CodePudding user response:

with another approach, you can also sort ascending or descending with the 3rd parameter.

const data = [
    {age: 22, status: true, group: 1},
    {age: 19, status: true, group: 1},
    {age: 30, status: false, group: 2},
    {age: 12, status: true, group: 1},
    {age: 23, status: false, group: 2},
    {age: 10, status: false, group: 2},
    {age: 10, status: false, group: 3},
]

const sorter = (data, sort, by) => {
    const test = (a, b, i) => Math.sign(a - b) ? (by[i]) * Math.sign(a - b) : 0;
    return data.sort((a, b) => sort.map((s, i) => test(a[s], b[s], i)).filter(item => item !== 0)[0]);
}


console.log(sorter(data, ['group', 'status', 'age'], [1, -1, -1]));

  • Related