簡體   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