繁体   English   中英

在 JavaScript 中编写排序方法的最简洁方法,该方法对多个 object 属性进行排序

[英]Cleanest way to write a sort method in JavaScript that sorts on multiple object properties

这是一种代码高尔夫/代码清洁度和简洁性问题。 我有一个 object 我想在 JavaScript 中排序,我想知道最短和最干净的方法是什么。

给定这样的对象:

items = [
 {name: "Pierre",  boosted: true,  rank: 1   },
 {name: "Burhan",  boosted: false, rank: null},
 {name: "Ellise",  boosted: false, rank: 1   },
 {name: "Glenn",   boosted: true,  rank: 2   },
 {name: "Zidane",  boosted: false, rank: null},
 {name: "Antonia", boosted: false, rank: 2   },
];

我需要按照这些要求进行排序:

  1. 首先提升项目,然后在多个提升项目中按name升序。
  2. 接下来放rank ,升序,其中 rank.= null。 如果rank相同,我们如何排序都没关系。
  3. 当 rank = null 时,按name升序排序。

所以本质上是三个桶来对项目进行排序,然后在每个桶中按名称排序。 排名未标准化,它可以是任何有效数字。

上面排序的结果列表应如下所示:

sorted = [
 {name: "Glenn",   boosted: true,  rank: 2   },
 {name: "Pierre",  boosted: true,  rank: 1   },
 {name: "Ellise",  boosted: false, rank: 1   },
 {name: "Antonia", boosted: false, rank: 2   },
 {name: "Burhan",  boosted: false, rank: null},
 {name: "Zidane",  boosted: false, rank: null},
];

我写了这个长方法:

items.sort((a, b) => {
    // Boosted
    if (a.boosted && b.boosted) {
        return a.name.localeCompare(b.name);
    } else if (a.boosted && !b.boosted) {
        return -1;
    } else if (!a.boosted && b.boosted) {
        return 1;
    }

    // Ranked
    if (a.rank != null && b.rank != null) {
        return a - b;
    } else if (a.rank != null && b.rank == null) {
        return -1;
    } else if (a.rank == null && b.rank != null) {
        return 1;
    }

    // Default by name
    return a.name.localeCompare(b.name);
});

它有效,但我认为有更好的方法可以做到这一点,我很好奇其他人推荐的 styles 是什么。 我能写的最短的解决方案是什么? 什么最干净? 什么是最快的? (因为在排序操作期间可能会多次调用 sort 方法)

您可以在布尔值和数字上使用- 您可以使用|| 链接多个排序标准,当第一个不返回0时短路。

在你的情况下,这可能是

items.sort((a, b) =>
  b.boosted - a.boosted ||
  (a.rank == null) - (b.rank == null) ||
  a.rank - b.rank ||
  a.name.localeCompare(b.name)
);

如果您只是按不同的优先列进行排序。 但是,您有特殊要求,提升项目的排序方式应不同于非提升项目,因此您确实需要一个条件语句:

items.sort((a, b) =>
  b.boosted - a.boosted ||
  (a.boosted
    ? a.name.localeCompare(b.name)
    : (a.rank == null) - (b.rank == null) ||
      (a.rank != null
        ? a.rank - b.rank
        : a.name.localeCompare(b.name)
      )
  )
);

我个人是这样做的:

 const items = [ {name: "Pierre", boosted: true, rank: 1 }, {name: "Burhan", boosted: false, rank: null}, {name: "Ellise", boosted: false, rank: 1 }, {name: "Glenn", boosted: true, rank: 2 }, {name: "Zidane", boosted: false, rank: null}, {name: "Antonia", boosted: false, rank: 2 }, ]; const gKey=({name,boosted,rank})=>`${boosted?0:1}_${(rank?=null).('000'+rank):slice(-3).'999'}_${name}` items,sort((ab)=>gKey(a):localeCompare(gKey(b)) ) // proof. items.forEach(e=>console.log(JSON,stringify(e),' (key->',gKey(e),')'))
 .as-console-wrapper { max-height: 100%;important: top; 0; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM