在java脚本中基于嵌套对象数组中的键对列表进行排序的最佳方法

Rol*_*ndo 7 javascript

我有以下内容:

var list = [
    {"item":[{a:5, a1:6, a2:7}, {b:3, b1:4, b2:2}]},
    {"item":[{a:1, a1:2, a2:3}, {b:4, b1:5, b2:6}]},
    {"item":[{a:2, a1:7, a2:4}, {b:3, b1:7, b2:1}]}
];
Run Code Online (Sandbox Code Playgroud)

假设我有list上面的变量,我该如何对其进行排序,使得具有item键中的所有直接对象list基于键(即"a1"或"b")以升序排序.请注意,它不会更改或重新排序列表list[x]["item"],但只会更改或直接列入list[x].

标准排序函数似乎只对数组中对象内的键进行排序,但我想基于位于数组中嵌套对象中的键进行排序.

排序这个的最佳方法是什么?

Sem*_*lon 4

所以你的主要问题是你需要在内部item数组中找到一个具有匹配属性的对象。因为您不知道它将位于哪个对象上。请注意,这里的一个限制是,您总是要对第一个找到的实例进行比较,即使其中多个对象item拥有比较属性。开始:

var list = [
    {"item":[{a:5, a1:6, a2:7}, {b:3, b1:4, b2:2}]},
    {"item":[{a:1, a1:2, a2:3}, {b:4, b1:5, b2:6}]},
    {"item":[{a:2, a1:7, a2:4}, {b:3, b1:7, b2:1}]}
];

function comparatorMaker(prop) {
    var findVal = function(acc, obj) {
        return acc || obj[prop];
    };

    return function(x, y) {
        if (!x.item && !y.item) return 0;
        if (x.item && !y.item) return -1;
        if (!x.item && y.item) return 1;

        var xVal = x.item.reduce(findVal, null) || 0;
        var yVal = y.item.reduce(findVal, null) || 0;

        return (xVal === yVal) ? 0 : (xVal > yVal) ? 1 : -1;
    };
}

var myComparator = comparatorMaker('a');

list.sort(myComparator); // element 1, element 2, element 0
Run Code Online (Sandbox Code Playgroud)

这里发生的是,我们为给定的属性名称生成一个唯一的比较器函数。它现在可以与任何:

var myComparator = comparatorMaker('b1');

list.sort(myComparator); // element 0, element 1, element 2
Run Code Online (Sandbox Code Playgroud)

我们在制作比较器函数时定义的 findVal 函数与 一起使用item.reduce。归约会迭代 的内容item并返回已找到的值或在当前检查的元素上查找值。实际上,这可以更有效地完成,因为item即使我们立即找到匹配项,我们最终也会迭代每个元素,但需要更多行代码来证明这一点,所以我保持简单。

比较器本身应该返回 1、0 或 -1,具体取决于结果值是大于-小于、等于还是小于-大于。比较器函数的前几行只是为了处理 in 中的元素list实际上不具有该item属性的情况,因为按照您表达问题的方式,听起来有时可能是这种情况。