Sort an array of objects by multiple properties

前端 未结 4 1027
我在风中等你
我在风中等你 2020-11-30 14:35

I have an array of objects like this:

var a = [
    { id: 1, score: 1, isCut: false, dnf: false },
    { id: 2, score: 2, isCut: false, dnf: false },
    { i         


        
相关标签:
4条回答
  • 2020-11-30 15:01

    This is a different approach, which uses an array for the sort order, which is irregular, if using dnf and isCut property without looking at both. If we take a both values to a truth table, then the sort order does not reflect the wanted order.

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

    To correct the sort order, I suggest to use an array for getting the right order.

    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; }

    0 讨论(0)
  • 2020-11-30 15:17

    Use comparator function from Array

    you can check answers here : Sort array of objects by string property value in JavaScript

    0 讨论(0)
  • 2020-11-30 15:20

    (Updated) Here's the answer of question you mentioned in comment.

    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
    });
    

    Result:

    [
      {"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} //
    ]
    
    0 讨论(0)
  • 2020-11-30 15:25

    You can do it in one line with Alasql library:

    var res = alasql('SELECT * FROM ? ORDER BY dnf, isCut, score, id',[a]);
    
    0 讨论(0)
提交回复
热议问题