How do you sort an array on multiple columns?

前端 未结 16 1078
面向向阳花
面向向阳花 2020-11-22 13:02

I have a multidimensional array. The primary array is an array of

[publicationID][publication_name][ownderID][owner_name] 

What I am tryin

16条回答
  •  有刺的猬
    2020-11-22 13:52

    Came across a need to do SQL-style mixed asc and desc object array sorts by keys.

    kennebec's solution above helped me get to this:

    Array.prototype.keySort = function(keys) {
    
    keys = keys || {};
    
    // via
    // https://stackoverflow.com/questions/5223/length-of-javascript-object-ie-associative-array
    var obLen = function(obj) {
        var size = 0, key;
        for (key in obj) {
            if (obj.hasOwnProperty(key))
                size++;
        }
        return size;
    };
    
    // avoiding using Object.keys because I guess did it have IE8 issues?
    // else var obIx = function(obj, ix){ return Object.keys(obj)[ix]; } or
    // whatever
    var obIx = function(obj, ix) {
        var size = 0, key;
        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                if (size == ix)
                    return key;
                size++;
            }
        }
        return false;
    };
    
    var keySort = function(a, b, d) {
        d = d !== null ? d : 1;
        // a = a.toLowerCase(); // this breaks numbers
        // b = b.toLowerCase();
        if (a == b)
            return 0;
        return a > b ? 1 * d : -1 * d;
    };
    
    var KL = obLen(keys);
    
    if (!KL)
        return this.sort(keySort);
    
    for ( var k in keys) {
        // asc unless desc or skip
        keys[k] = 
                keys[k] == 'desc' || keys[k] == -1  ? -1 
              : (keys[k] == 'skip' || keys[k] === 0 ? 0 
              : 1);
    }
    
    this.sort(function(a, b) {
        var sorted = 0, ix = 0;
    
        while (sorted === 0 && ix < KL) {
            var k = obIx(keys, ix);
            if (k) {
                var dir = keys[k];
                sorted = keySort(a[k], b[k], dir);
                ix++;
            }
        }
        return sorted;
    });
    return this;
    };
    

    sample usage:

    var obja = [
      {USER:"bob",  SCORE:2000, TIME:32,    AGE:16, COUNTRY:"US"},
      {USER:"jane", SCORE:4000, TIME:35,    AGE:16, COUNTRY:"DE"},
      {USER:"tim",  SCORE:1000, TIME:30,    AGE:17, COUNTRY:"UK"},
      {USER:"mary", SCORE:1500, TIME:31,    AGE:19, COUNTRY:"PL"},
      {USER:"joe",  SCORE:2500, TIME:33,    AGE:18, COUNTRY:"US"},
      {USER:"sally",    SCORE:2000, TIME:30,    AGE:16, COUNTRY:"CA"},
      {USER:"yuri", SCORE:3000, TIME:34,    AGE:19, COUNTRY:"RU"},
      {USER:"anita",    SCORE:2500, TIME:32,    AGE:17, COUNTRY:"LV"},
      {USER:"mark", SCORE:2000, TIME:30,    AGE:18, COUNTRY:"DE"},
      {USER:"amy",  SCORE:1500, TIME:29,    AGE:19, COUNTRY:"UK"}
    ];
    
    var sorto = {
      SCORE:"desc",TIME:"asc", AGE:"asc"
    };
    
    obja.keySort(sorto);
    

    yields the following:

     0: {     USER: jane;     SCORE: 4000;    TIME: 35;       AGE: 16;    COUNTRY: DE;   }
     1: {     USER: yuri;     SCORE: 3000;    TIME: 34;       AGE: 19;    COUNTRY: RU;   }
     2: {     USER: anita;    SCORE: 2500;    TIME: 32;       AGE: 17;    COUNTRY: LV;   }
     3: {     USER: joe;      SCORE: 2500;    TIME: 33;       AGE: 18;    COUNTRY: US;   }
     4: {     USER: sally;    SCORE: 2000;    TIME: 30;       AGE: 16;    COUNTRY: CA;   }
     5: {     USER: mark;     SCORE: 2000;    TIME: 30;       AGE: 18;    COUNTRY: DE;   }
     6: {     USER: bob;      SCORE: 2000;    TIME: 32;       AGE: 16;    COUNTRY: US;   }
     7: {     USER: amy;      SCORE: 1500;    TIME: 29;       AGE: 19;    COUNTRY: UK;   }
     8: {     USER: mary;     SCORE: 1500;    TIME: 31;       AGE: 19;    COUNTRY: PL;   }
     9: {     USER: tim;      SCORE: 1000;    TIME: 30;       AGE: 17;    COUNTRY: UK;   }
     keySort: {  }
    

    (using a print function from here)

    here is a jsbin example.

    edit: cleaned up and posted as mksort.js on github.

提交回复
热议问题