数组一个更优雅的次要排序 [英] A more elegant secondary sort for arrays

查看:209
本文介绍了数组一个更优雅的次要排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要的阵列上执行排序,如果两个元素相等,然后我需要在这些元素中一个不同的密钥进行辅助排序。在看看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);
});

还是用上面的对比更紧凑

\r
\r

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

\r
\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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆