JavaScript 对基于属性数组的对象数组进行排序

时间:2021-03-22 14:57:10

标签: javascript arrays

例如我有这个数据集:

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" },
];

我需要根据 records 数组中的条件对 order 数组进行排序。 我最终得到了这个解决方案:

const sorted = records.sort(
  (recordA, recordB) =>
    recordA.job.localeCompare(recordB.job) || recordA.age - recordB.age
);

但我无法理解如何使用 order 数组而不是硬编码 jobage 属性。 order 数组可以有很多属性。

3 个答案:

答案 0 :(得分:4)

您可以对所需订单进行闭包并检查值是否有限,然后返回增量或将值视为字符串。

只要返回值为falsy,内部排序函数就会进行迭代,并以此值作为排序的返回值。

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; }

答案 1 :(得分:3)

只需遍历订单数据并进行比较:

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; }

答案 2 :(得分:2)

您可以使用 (a[key] > b[key]) - (a[key] < b[key]) 在词法或数字上比较两个值(如果两者都是数字)。然后可以像这样使用:

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

direction 的实现留给读者

相关问题