我有以下内容:
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},b1:7,b2:1}]} ];
假设我有上面的变量列表,我该如何对其进行排序,使得列表中具有项密钥的所有直接对象基于密钥(即“a1”或“b”)按升序排序.请注意,它不会更改或重新排序list [x] [“item”]中的列表,而只会更改list [x]中的直接项.
标准排序函数似乎只对数组中对象内的键进行排序,但我想根据位于数组中嵌套对象中的键进行排序.
排序这个的最佳方法是什么?
解决方法
所以你的主要问题是你需要在匹配属性的内部项数组中找到一个对象.因为您不知道它将位于哪个对象上.请注意,这里的限制是您总是要在第一个找到的实例上进行比较,即使item中有多个对象拥有比较属性.开始:
var list = [ {"item":[{a:5,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
这里发生的是我们为给定的属性名称生成一个唯一的比较器函数.它现在适用于任何:
var myComparator = comparatorMaker('b1'); list.sort(myComparator); // element 0,element 1,element 2
我们在制作比较器函数时定义的findVal函数与item.reduce一起使用.缩减迭代item的内容并返回已找到的值或查找当前检查元素的值.实际上,这可以更有效地完成,因为即使我们立即找到匹配项,我们最终也会迭代项中的每个元素,但是需要更多行代码才能证明这一点,所以我保持简单.
比较器本身应返回1,0或-1,具体取决于是否发现结果值更大,更小,更小或更小.比较器函数的前几行只是处理列表中的元素实际上没有item属性的情况,因为你对这个问题的表达方式,听起来有时可能就是这种情况.