[英]JavaScript sort an array of objects based array of properties
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.我需要根据
order
数组中的条件对records
数组进行排序。 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.但我无法理解如何使用
order
数组而不是硬编码job
和age
属性。 The order
array can have many properties. order
数组可以有很多属性。
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.内部排序 function 迭代,只要返回值是假的,并以此值作为返回值进行排序。
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).您可以使用
(a[key] > b[key]) - (a[key] < b[key])
在词法或数字上比较两个值(如果两者都是数字)。 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 direction
的实现留给读者
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.