[英]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 },
];
我需要按照这些要求进行排序:
name
升序。rank
,升序,其中 rank.= null。 如果rank
相同,我们如何排序都没关系。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.