数组一个更优雅的次要排序 [英] A more elegant secondary sort for arrays
问题描述
我需要的阵列上执行排序,如果两个元素相等,然后我需要在这些元素中一个不同的密钥进行辅助排序。在看看Mozilla开发者网络文档的阵列的.sort 有一个在code一个很好的片段在底部处理第一个排序。我喜欢它,因为它是简洁,展示了如何编写功能强大的JS。
下面是基于来自MDN的code是我的尝试。这不正确的第一个排序。
//数组排序
VAR名单= [{名称:'三角洲',参考:456},{名称:'三角洲',参考:123},{名称:'阿尔法',参考:789},{名称:'查理',REF:012 },{名称:'喝彩',编号:345}];//临时数组保存与位置和排序值对象
VAR映射= list.map(功能(EL,I){
返回{
指数:我,
值:el.name.toLowerCase()
secondaryValue:el.ref
};
});//排序包含减少值映射数组
mapped.sort(功能(A,B){
返回+(a.value中> b.value)|| +(a.value中=== b.value) - 1;
});//为生成的顺序容器
VAR的结果= mapped.map(功能(EL){
返回列表[el.index]
});的console.log(名单);
的console.log(结果);
现在我知道我可以修改这样的比较函数来完成第二排序的要求:
//包含排序与减少的价值映射数组
mapped.sort(功能(A,B){
如果(a.value中=== b.value){
返回+(a.secondaryValue> b.secondaryValue)|| +(a.secondaryValue === b.secondaryValue) - 1;
} 返回+(a.value中> b.value)|| - 1;
});
不过,对我来说,这个失去了一些收益+的魅力(a.value中> b.value)|| +(a.value中=== b.value) - 1;
- 这在我看来是pretty酷
问:是否有执行辅助排序更优雅的方式
?的限制的:唯一的纯JS。 ES5兼容preferably但有兴趣听到的话,ES6可以提供帮助。
您可以链或 ||
,因为相同的价值观进行评估与逻辑排序比较 0
,这是falsey所以接下来的部分进行评估。
mapped.sort(功能(A,B){
返回(+(a.value中> b.value)|| +(a.value中=== b.value) - 1)||
(+(a.secondaryValue> b.secondaryValue)|| +(a.secondaryValue === b.secondaryValue) - 1);
});
还是用上面的对比更紧凑
VAR名单= [{名称:'三角洲',参考:456},{名称:'三角洲',参考:123},{名称:'阿尔法',参考:789},{名称:'查理',参考:12},{名称:'喝彩',编号:345}],\r
映射= list.map(功能(EL,I){\r
返回{\r
指数:我,\r
值:el.name.toLowerCase()\r
secondaryValue:el.ref\r
};\r
});\r
\r
mapped.sort(功能(A,B){\r
返回a.value.localeCompare(b.value)|| a.secondaryValue - b.secondaryValue;\r
});\r
\r
VAR的结果= mapped.map(功能(EL){\r
返回列表[el.index]\r
});\r
\r
的document.write('< pre>'+ JSON.stringify(结果,0,4)+'< / pre>');
\r
I need to perform a sort on an array and if two elements are equal I then need to perform a secondary sort on a different key within those elements. Having a look at the Mozilla Developer Network docs for array.sort there is a nice snippet at code at the bottom to handle the first sort. I liked it because it was succinct and shows how you can write powerful JS.
Here is what I tried based on the code from MDN. This correctly does the first sort.
// the array to be sorted
var list = [{name:'Delta', ref: 456}, {name:'Delta', ref: 123}, {name:'alpha', ref: 789}, {name:'CHARLIE', ref: 012}, {name:'bravo', ref: 345}];
// temporary array holds objects with position and sort-value
var mapped = list.map(function (el, i) {
return {
index: i,
value: el.name.toLowerCase(),
secondaryValue: el.ref
};
});
// sorting the mapped array containing the reduced values
mapped.sort(function (a, b) {
return +(a.value > b.value) || +(a.value === b.value) - 1;
});
// container for the resulting order
var result = mapped.map(function (el) {
return list[el.index];
});
console.log(list);
console.log(result);
Now I know I can modify the comparison function like this to complete the requirement of the secondary sort:
// sorting the mapped array containing the reduced values
mapped.sort(function (a, b) {
if (a.value === b.value){
return +(a.secondaryValue > b.secondaryValue) || +(a.secondaryValue === b.secondaryValue) - 1;
}
return +(a.value > b.value) || - 1;
});
But, to me, this loses some of the charm of return +(a.value > b.value) || +(a.value === b.value) - 1;
- which is pretty cool in my opinion.
Question: Is there a more elegant way to perform the secondary sort?
Restriction: Pure JS only. ES5 compatible preferably but interested to hear if ES6 can help.
You can chain the sort comparison with a logic or ||
, because same values are evaluated to 0
and that is falsey so the next part is evaluated.
mapped.sort(function (a, b) {
return (+(a.value > b.value) || +(a.value === b.value) - 1) ||
(+(a.secondaryValue > b.secondaryValue) || +(a.secondaryValue === b.secondaryValue) - 1);
});
Or use more compact version of the above comparison
var list = [{name:'Delta', ref: 456}, {name:'Delta', ref: 123}, {name:'alpha', ref: 789}, {name:'CHARLIE', ref: 12}, {name:'bravo', ref: 345}],
mapped = list.map(function (el, i) {
return {
index: i,
value: el.name.toLowerCase(),
secondaryValue: el.ref
};
});
mapped.sort(function (a, b) {
return a.value.localeCompare(b.value) || a.secondaryValue - b.secondaryValue;
});
var result = mapped.map(function (el) {
return list[el.index];
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
这篇关于数组一个更优雅的次要排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!