簡體   English   中英

按多個屬性對對象數組進行排序

[英]Sort an array of objects by multiple properties

我有一個像這樣的對象數組:

var a = [
    { id: 1, score: 1, isCut: false, dnf: false },
    { id: 2, score: 2, isCut: false, dnf: false },
    { id: 3, score: 3, isCut: false, dnf: false },
    { id: 4, score: 4, isCut: false, dnf: false },
    { id: 5, score: 5, isCut: true, dnf: true },
    { id: 6, score: 6, isCut: true, dnf: false },
    { id: 7, score: 7, isCut: true, dnf: false },
    { id: 8, score: 8, isCut: true, dnf: false },
    { id: 9, score: 9, isCut: true, dnf: false },
    { id: 10, score: 0, isCut: false, dnf: false },
    { id: 11, score: -1, isCut: false, dnf: false },
    { id: 12, score: -2, isCut: false, dnf: true },
    { id: 13, score: -3, isCut: false, dnf: false },
    { id: 14, score: -4, isCut: false, dnf: false },
    { id: 15, score: -5, isCut: false, dnf: false },
    { id: 16, score: 10, isCut: true, dnf: false }
];

我需要按以下標准對數組進行分組和排序:

  1. 如果dnf為真,則對象移至底部; 所有dnf -objects 應按分數排序
  2. 如果isCut為真,則對象進入底部,但在dnf之上; 所有isCut -objects 應按分數排序
  3. 其余應按score排序,如果分數相等, id

(更新)這是您在評論中提到的問題的答案。

a.sort(function(a, b) {
  if (a.dnf != b.dnf) {
    return a.dnf ? 1 : -1;
  }
  if (!(a.dnf && b.dnf) && a.isCut != b.isCut) {
    return a.isCut ? 1 : -1;
  }
  if (a.score != b.score) {
    return b.score - a.score; // descending
  }
  return b.id - a.id; // descending
});

結果:

[
  {"id":4,"score":4,"isCut":false,"dnf":false},   // the rest: order by score, id
  {"id":3,"score":3,"isCut":false,"dnf":false},   //
  {"id":2,"score":2,"isCut":false,"dnf":false},   //
  {"id":1,"score":1,"isCut":false,"dnf":false},   //
  {"id":10,"score":0,"isCut":false,"dnf":false},  //
  {"id":11,"score":-1,"isCut":false,"dnf":false}, //
  {"id":13,"score":-3,"isCut":false,"dnf":false}, //
  {"id":14,"score":-4,"isCut":false,"dnf":false}, //
  {"id":15,"score":-5,"isCut":false,"dnf":false}, //
  {"id":16,"score":10,"isCut":true,"dnf":false}, // isCut: order by score, id
  {"id":9,"score":9,"isCut":true,"dnf":false},   //
  {"id":8,"score":8,"isCut":true,"dnf":false},   //
  {"id":7,"score":7,"isCut":true,"dnf":false},   //
  {"id":6,"score":6,"isCut":true,"dnf":false},   //
  {"id":5,"score":5,"isCut":true,"dnf":true},   // dnf: order by score, id
  {"id":12,"score":-2,"isCut":false,"dnf":true} //
]

使用 Array 中的比較器函數

您可以在此處查看答案: 在 JavaScript 中按字符串屬性值對對象數組進行排序

這是一種不同的方法,它使用一個數組作為排序順序,如果使用dnfisCut屬性而不查看兩者,則這是不規則的。 如果我們將兩個值都放入真值表,則排序順序不會反映所需的順序。

 2*dnf+isCut dnf isCut value order -------- -------- -------- -------- 0 0 0 0 0 1 1 1 1 1 3 2 1 0 2 3

為了更正排序順序,我建議使用數組來獲得正確的順序。

 var data = [{ id: 1, score: 1, isCut: false, dnf: false }, { id: 2, score: 2, isCut: false, dnf: false }, { id: 3, score: 3, isCut: false, dnf: false }, { id: 4, score: 4, isCut: false, dnf: false }, { id: 5, score: 5, isCut: true, dnf: true }, { id: 6, score: 6, isCut: true, dnf: false }, { id: 7, score: 7, isCut: true, dnf: false }, { id: 8, score: 8, isCut: true, dnf: false }, { id: 9, score: 9, isCut: true, dnf: false }, { id: 10, score: 0, isCut: false, dnf: false }, { id: 11, score: -1, isCut: false, dnf: false }, { id: 12, score: -2, isCut: false, dnf: true }, { id: 13, score: -3, isCut: false, dnf: false }, { id: 14, score: -4, isCut: false, dnf: false }, { id: 15, score: -5, isCut: false, dnf: false }, { id: 16, score: 10, isCut: true, dnf: false }]; data.sort(function (a, b) { function order(dnf, isCut) { return [0, 1, 3, 2][dnf * 2 + isCut]; } return order(a.dnf, a.isCut) - order(b.dnf, b.isCut) || b.score - a.score; }); console.log(data);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

您可以使用Alasql庫在一行中完成此操作

var res = alasql('SELECT * FROM ? ORDER BY dnf, isCut, score, id',[a]);

在jsFiddle上使用數據嘗試該示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM