我有以下内容:
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].
标准排序函数似乎只对数组中对象内的键进行排序,但我想基于位于数组中嵌套对象中的键进行排序.
排序这个的最佳方法是什么?
所以你的主要问题是你需要在内部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属性的情况,因为按照您表达问题的方式,听起来有时可能是这种情况。