【问题标题】:javascript how sort array of objects by two rule? [duplicate]javascript如何通过两条规则对对象数组进行排序? [复制]
【发布时间】:2018-08-30 08:09:01
【问题描述】:

我有一个这样的对象列表:

 [
      {"groups":["aaa"]},
      {"groups":["bbb"]},
      {"groups":["ccc"]},
      {"groups":["ddd"]},
      {"groups":["eee"]},
      {"groups":["fff"]},
      {"groups":["ggg"]},
      {"groups":["hhh"]},
      {"groups":["iii"]},
      {"groups":["mmm", "mmm"]}
      {"groups":["lll", "lll"]}
];

我想按字母顺序将具有多个组的所有对象按字母顺序放在列表的末尾,并将其他对象与一组放在列表的开头而不更改原始顺序。

这是我的代码

var list = [
  {"groups":["aaa"]},
  {"groups":["bbb"]},
  {"groups":["ccc"]},
  {"groups":["ddd"]},
  {"groups":["eee"]},
  {"groups":["fff"]},
  {"groups":["ggg"]},
  {"groups":["hhh"]},
  {"groups":["iii"]},
  {"groups":["mmm", "mmm"]},
  {"groups":["lll", "lll"]}
];

list.sort(function(a, b){
        var aIsGroup = (a.groups.length > 1);
        var bIsGroup = (b.groups.length > 1);

        if (aIsGroup && !bIsGroup) {
            return 1;
        } else if (!aIsGroup && bIsGroup) {
            return -1;
        } else if(aIsGroup && bIsGroup){
            return a.groups[0].toLowerCase().localeCompare(b.groups[0].toLowerCase());
        }
        return 0;
});

console.log(list);

在sn -p中可以看到当前的输出,但是预期的输出是:

[
  {
    "groups": [
      "aaa"
    ]
  },
  {
    "groups": [
      "bbb"
    ]
  },
  {
    "groups": [
      "ccc"
    ]
  },
  {
    "groups": [
      "ddd"
    ]
  },
  {
    "groups": [
      "eee"
    ]
  },
  {
    "groups": [
      "fff"
    ]
  },
  {
    "groups": [
      "ggg"
    ]
  },
  {
    "groups": [
      "hhh"
    ]
  },
  {
    "groups": [
      "iii"
    ]
  },
  {
    "groups": [
      "lll",
      "lll"
    ]
  },
  {
    "groups": [
      "mmm",
      "mmm"
    ]
  }
]

【问题讨论】:

  • Javascript 的 sort 不保证稳定的排序。任何“相等”的元素都有未定义的顺序。请参阅副本以实现 stable 排序。
  • 为什么不先过滤具有多个组的条目,将它们从原始数组中删除,然后附加它们?
  • @connexo 好主意..
  • @connexo 为什么不把这个作为答案
  • a.groups.length > 1 更改为a.groups.length > 0b.groups.length > 1 更改为b.groups.length > 0

标签: javascript


【解决方案1】:

正如@deceze 在评论中所说的

Javascript 的排序不能保证稳定的排序。任何“相等”的元素都有未定义的顺序。请参阅副本以实现稳定排序

但您可以这样做以使它们保持与原始顺序相同的顺序(稳定排序)

var list = [
  {"groups":["aaa"]},
  {"groups":["bbb"]},
  {"groups":["ccc"]},
  {"groups":["mmm", "mmm"]},
  {"groups":["ddd"]},
  {"groups":["fff"]},
  {"groups":["eee"]},
  {"groups":["ggg"]},
  {"groups":["hhh"]},
  {"groups":["iii"]},
  {"groups":["lll", "lll"]}
];

list.sort(function(a, b){
        var aIsGroup = (a.groups.length > 1);
        var bIsGroup = (b.groups.length > 1);

        if (aIsGroup && !bIsGroup) {
            return 1;
        } else if (!aIsGroup && bIsGroup) {
            return -1;
        } else if(aIsGroup && bIsGroup) {
            return a.groups[0].toLowerCase().localeCompare(b.groups[0].toLowerCase());
        }
        // keep in the same order
        return (list.indexOf(a) < list.indexOf(b)) ? -1 : 1;
});

console.log(list);

【讨论】:

  • 我不确定标准是对它们进行词法排序,但它们应该保留其原始顺序(即稳定排序)。
  • @deceze 你可能是对的,需要询问操作
  • @deceze 重读你是对的问题
  • @deceze,谢谢,但我只想要(a.groups.length &gt; 1) &amp;&amp; (b.groups.length &gt; 1)的字母顺序
  • @ar099968 已编辑 ;) fffeee 混合在一起,因为我在声明数组时混合了它们以在单元素上显示没有词法
猜你喜欢
  • 2019-09-24
  • 2020-05-18
  • 2011-07-01
  • 2021-08-28
  • 2014-12-07
  • 2018-02-08
  • 2022-01-20
相关资源
最近更新 更多