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]));