Array.sort safari问题

时间:2017-08-14 13:47:15

标签: javascript arrays sorting

我有阵列:

var arr = [
    {id: "d", sequence: 3},
    {id: "c", sequence: 4},
    {id: "b", sequence: 2},
    {id: "a", sequence: 1},
    {id: "e"}
];

并希望按照逻辑对其进行排序:

  • 没有sequence的元素应该是第一个
  • 其他应按降序排列sequence

我的解决方案是:

arr.sort(function(a, b) {
  if (!a.sequence || !b.sequence) return 1;
  return b.sequence - a.sequence;
});

我预计会遵循以下顺序:

[{id: "e"}, {id: "c", sequence: 4}, {id: "d", sequence: 3}, ...]

但在safari收到:

[
  {id: "c", sequence: 4}, 
  {id: "d", sequence: 3},
  {id: "b", sequence: 2},
  {id: "a", sequence: 1},
  {id: "e"}
]

为什么在Safari {id: "e"}中是最后一个元素,在Chrome和Firefox中它是第一个?

感谢您提前!

2 个答案:

答案 0 :(得分:7)

您的排序比较器没有按照您的意愿执行操作。如果你想缺少一个“序列”属性来表示元素应该在元素之前这样的属性,你的返回值必须反映出:

arr.sort(function(a, b) {
  if (("sequence" in a) && !("sequence" in b))
    return 1;
  if (("sequence" in b) && !("sequence" in a))
    return -1;
  if (!("sequence" in a) && !("sequence" in b))
    return 0;
  return b.sequence - a.sequence;
});

(这可以用更少的代码来完成;为了清楚起见,它是明确的。)重要的是,排序比较器函数总是为每对元素返回一致的结果(按任意顺序)。

您的现有代码在浏览器之间的行为有所不同,因为运行时系统之间的排序实现会有所不同。

答案 1 :(得分:1)

您可以像这样使用#sort

  1. return表达式的第一部分检查sequence是否存在,
  2. ,而第二部分以降序顺序排序arr
  3. 见下面的演示:

    var arr=[{id:"d",sequence:3},{id:"c",sequence:4},{id:"b",sequence:2},{id:"a",sequence:1},{id:"e"}];
    
    var result = arr.sort(function(a, b) {
      return +('sequence' in a) - +('sequence' in b) || b.sequence - a.sequence
    });
    
    console.log(result);
    .as-console-wrapper{top:0;max-height:100%!important;}