首页 > 解决方案 > 在 JavaScript 中编写对多个对象属性进行排序的排序方法的最简洁方法

问题描述

这是一种代码高尔夫/代码清洁度和简洁性问题。我有一个我想在 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);
});

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

标签: javascriptsorting

解决方案


您可以-在布尔值和数字上使用。您可以使用||链接多个排序条件,当第一个不返回时短路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)
      )
  )
);

推荐阅读