【问题标题】:Grouped sorting on a JS arrayJS数组上的分组排序
【发布时间】:2013-04-23 08:03:26
【问题描述】:

我有一个包含两个属性的对象数组:名称和时间。

例如:

array = [
    {name: "ANDY", hours: 40 }, 
    {name: "ANDY", hours: 50 }, 
    {name: "GREG", hours: 40 },
]

例如,在我的数组中,我希望排序的结果是安迪的小时数最多,然后安迪的小时数略少,然后是格雷格,因为他的名字按字母顺序排在后面,依此类推。

由于 array.sort() 函数传递数组的两个元素进行比较,我意识到这不是我要走的路,但未能提出一个优雅的解决方案。请帮帮我。

【问题讨论】:

标签: javascript


【解决方案1】:

array = [
    {name: "ANDY", hours: 40 }, 
    {name: "GREG", hours: 40 },
    {name: "ANDY", hours: 50 }, 
]

function cmp(x, y) {
  return x > y ? 1 : (x < y ? -1 : 0);
}


array.sort(function(a, b) {
  return cmp(a.name, b.name) || cmp(b.hours, a.hours)
})

console.log(array)

如果 javascript 有一个 spaceship operator 那就更优雅了。请注意,此代码很容易扩展以使用更多属性:

ary.sort(function(a, b) {
    return cmp(a.name, b.name) || cmp(a.age, b.age) || cmp(b.hours, a.hours) || ....
})

【讨论】:

  • 逻辑很难。谢谢!
  • 您在 sort 的 return 语句和 sort 函数中缺少分号。
  • 分号是可选的
【解决方案2】:
var arr = [{
    name: "GREG",
    hours: "40"
}, {
    name: "ANDY",
    hours: "50"
}, {
    name: "ANDY",
    hours: "40"
}];

Array.prototype.sortOn = function(conds){
    this.sort(function(a, b){
        for(var i=0; i < conds.length; i++){
            var c = conds[i].split(" ");
            if(a[c[0]] < b[c[0]]){
                return c[1] == "asc" ? -1:1;
            }
            if(a[c[0]] > b[c[0]]){
                return c[1] == "asc" ? 1:-1;
            }
        }
        return 0;
    });
    return this;
}

arr.sortOn(["name asc", "hours dsc"]);

【讨论】:

  • 对不起,这是错误的。您不能从排序函数返回 x &gt; y
  • 不,这是同样的错误。您应该返回 -1、1 或 0,而不仅仅是 1、-1。
  • @thg435。试图找到一个懒惰的解决方案。已考虑所有条件进行了更正。谢谢:)
【解决方案3】:
obj.sort(function(item1,item2) {
  if ( item1.Name < item2.Name )
    return -1;
  if ( item1.Name > item2.Name )
    return 1;
  return item1.Hours - item2.Hours;
});

【讨论】:

    【解决方案4】:

    您可以按名称排序,然后按小时数

    对具有相同名称的元素进行排序

    例子:

    var array = [{"Name":"ANDY", "Hours":40},
                 {"Name":"ANDY", "Hours":50},
                 {"Name":"GREG", "Hours":40}];
    
    
    var sortedArray = array.sort(function(a,b) {
                return (a["Name"] > b["Name"]) ? 1 : -1;
        }).sort(function(a,b) {
                if(a["Name"] == b["Name"])
                    return (a["Hours"] < b["Hours"]) ? 1 : -1;
                else 
                    return 0;
        });
    

    【讨论】:

    • Javascript 排序不保证稳定,结果可能因实现而异。
    • 为什么要通过括号而不是点符号来访问属性?
    • 是的,这两种符号都适用于这个特定的问题。不知道为什么我更喜欢使用括号。我想这是因为它更通用,如果有人对包含空格字符的属性有类似的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    • 2022-01-07
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多