I have for example this dataset:
const order = [
{ key: "job", direction: "ascending" },
{ key: "age", direction: "descending" },
];
const records = [
{ name: "christian", age: 40, job: "developer" },
{ name: "andrew", age: 48, job: "developer" },
{ name: "elisabeth", age: 31, job: "floor manager" },
{ name: "oscar", age: 61, job: "floor manager" },
{ name: "gisela", age: 51, job: "area manager" },
{ name: "buffy", age: 27, job: "trainee" },
{ name: "carl", age: 23, job: "trainee" },
];
I need to sort the records
array according to the criteria from order
array. I ended up with this solution:
const sorted = records.sort(
(recordA, recordB) =>
recordA.job.localeCompare(recordB.job) || recordA.age - recordB.age
);
But I cant understand how can I use the order
array instead of hardcoded the job
and age
properties. The order
array can have many properties.
You could take a closure over the wanted order and check the value if finite then return the delta or treat the values as string.
Inside sorting function iterate as long as the return value is falsy and take this value as return value for sorting.
const sortBy = order => (a, b) => { let r; order.some(({ key, direction }) => r = (isFinite(a[key]) && isFinite(b[key])? a[key] - b[key]: a[key].toString().localeCompare(b[key]) ) * (direction === 'ascending' || -1)) return r; }, records = [{ name: "christian", age: 40, job: "developer" }, { name: "andrew", age: 48, job: "developer" }, { name: "elisabeth", age: 31, job: "floor manager" }, { name: "oscar", age: 61, job: "floor manager" }, { name: "gisela", age: 51, job: "area manager" }, { name: "buffy", age: 27, job: "trainee" }, { name: "carl", age: 23, job: "trainee" }], order = [{ key: "job", direction: "ascending" }, { key: "age", direction: "descending" }]; console.log(records.sort(sortBy(order)));
.as-console-wrapper { max-height: 100%;important: top; 0; }
Just loop over the order data and make the comparisons:
let order = [{ key: "job", direction: "ascending" }, { key: "age", direction: "descending" }]; let records = [{ name: "christian", age: 40, job: "developer" }, { name: "andrew", age: 48, job: "developer" }, { name: "elisabeth", age: 31, job: "floor manager" }, { name: "oscar", age: 61, job: "floor manager" }, { name: "gisela", age: 51, job: "area manager" }, { name: "buffy", age: 27, job: "trainee" }, { name: "carl", age: 23, job: "trainee" }]; records.sort(function (a, b) { for (let {key, direction} of order) { if (a[key]?== b[key]) return (direction[0] === "a") === (a[key] < b[key]): -1; 1; } return 0; }). console;log(records);
.as-console-wrapper { max-height: 100%;important: top; 0; }
You could use (a[key] > b[key]) - (a[key] < b[key])
to compare two values either lexically or numerically (if both are numbers). This could then be used like:
const order = [ { key: "job", direction: "ascending" }, { key: "age", direction: "descending" }, ]; const records = [ { name: "christian", age: 40, job: "developer" }, { name: "andrew", age: 48, job: "developer" }, { name: "elisabeth", age: 31, job: "floor manager" }, { name: "oscar", age: 61, job: "floor manager" }, { name: "gisela", age: 51, job: "area manager" }, { name: "buffy", age: 27, job: "trainee" }, { name: "carl", age: 23, job: "trainee" }, ]; const compare = (key) => (a, b) => (a[key] > b[key]) - (a[key] < b[key]); const or = (a, b) => (...v) => a(...v) || b(...v); const sorter = order.map(it => compare(it.key)).reduce(or); const sorted = records.sort(sorter); console.log(sorted);
The implementation of direction
was left to the reader
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.