How to sort an array of objects with multiple field values in JavaScript

前端 未结 5 1840
迷失自我
迷失自我 2020-12-10 13:56

I found a great method to sort an array of objects based on one of the properties as defined at:

Sort array of objects by string property value in JavaScript

相关标签:
5条回答
  • 2020-12-10 14:12

    You may also want to have a look at thenBy.js: https://github.com/Teun/thenBy.js

    It allows you to use the standard Array.sort, but with firstBy().thenBy().thenBy() style.

    0 讨论(0)
  • 2020-12-10 14:19

    I now this post is quite old, anyway I found it today and quoting Ege Özcan, I improved his excellent solution implementing DESC-ASC SQL-Like functionality for anyone interested (http://jsfiddle.net/ZXedp/65/):

    function dynamicSortMultiple() {
        var props=[];
        /*Let's separate property name from ascendant or descendant keyword*/
        for(var i=0; i < arguments.length; i++){
            var splittedArg=arguments[i].split(/ +/);
            props[props.length]=[splittedArg[0], (splittedArg[1] ? splittedArg[1].toUpperCase() : "ASC")];
        }
        return function (obj1, obj2) {
            var i = 0, result = 0, numberOfProperties = props.length ;
            /*Cycle on values until find a difference!*/
            while(result === 0 && i < numberOfProperties) {
                result = dynamicSort(props[i][0], props[i][1])(obj1, obj2);
                i++;
            }
            return result;
        }
    }
    
    /*Base function returning -1,1,0 for custom sorting*/
    function dynamicSort(property, isAscDesc) { 
        return function (obj1,obj2) {
            if(isAscDesc==="DESC"){
                return ((obj1[property] > obj2[property]) ? (-1) : ((obj1[property] < obj2[property]) ? (1) : (0)));
            }
            /*else, if isAscDesc==="ASC"*/
            return ((obj1[property] > obj2[property]) ? (1) : ((obj1[property] < obj2[property]) ? (-1) : (0)));
        }
    }
    

    call the function by something like this:

    arr.sort(dynamicSortMultiple("c DESC","b Asc","a"));
    
    0 讨论(0)
  • 2020-12-10 14:21

    I created a multi-parameter version of that dynamicSort function:

    function dynamicSort(property) { 
        return function (obj1,obj2) {
            return obj1[property] > obj2[property] ? 1
                : obj1[property] < obj2[property] ? -1 : 0;
        }
    }
    
    function dynamicSortMultiple() {
        /*
         * save the arguments object as it will be overwritten
         * note that arguments object is an array-like object
         * consisting of the names of the properties to sort by
         */
        var props = arguments;
        return function (obj1, obj2) {
            var i = 0, result = 0, numberOfProperties = props.length;
            /* try getting a different result from 0 (equal)
             * as long as we have extra properties to compare
             */
            while(result === 0 && i < numberOfProperties) {
                result = dynamicSort(props[i])(obj1, obj2);
                i++;
            }
            return result;
        }
    }
    

    I created an array as follows:

    var arr = [
        {a:"a",b:"a",c:"a"},
        {a:"b",b:"a",c:"b"},
        {a:"b",b:"a",c:"a"},
        {a:"b",b:"a",c:"b"},
        {a:"b",b:"b",c:"a"},
        {a:"b",b:"b",c:"b"},
        {a:"b",b:"b",c:"a"},
        {a:"b",b:"b",c:"b"},
        {a:"b",b:"b",c:"a"},
        {a:"b",b:"b",c:"b"},
        {a:"b",b:"b",c:"a"},
        {a:"c",b:"b",c:"b"},
        {a:"c",b:"c",c:"a"}
    ];
    

    and it worked when I did,

    arr.sort(dynamicSortMultiple("c","b","a"));
    

    And here is a working example: http://jsfiddle.net/ZXedp/

    0 讨论(0)
  • 2020-12-10 14:24

    The easiest way to perform a Javascript Multi-Criteria Sort (or Multi-Parameter Sort), is to use .sort, concatenate the multiple parameters together, and compare the two stings.

    For example:

    data.sort(function (a, b) {
    
      var aConcat = a["property1"] + a["property2"];
      var bConcat = b["property1"] + b["property2"];
    
      if (aConcat > bConcat) {
        return 1;
      } else if (aConcat < bConcat) {
        return -1;
      } else {
        return 0;
      }
    
    });
    

    I've included a JsFiddle Script here: http://jsfiddle.net/oahxg4u3/6/

    0 讨论(0)
  • 2020-12-10 14:29

    Here is my solution. It faster than lodash's _.sortBy() multi-column sort function in about two times (see http://jsperf.com/multi-column-sort. I generate text of sorting function, then use it in standard .sort(). It works in Chrome and Firefox as well.

    function multiColumnSort(arr,sf) {
        var s = '';
        sf.forEach(function(f,idx) {
            s += 'if(arguments[0].'+f+'>arguments[1].'+f+')return 1;';
            s += 'else if(arguments[0].'+f+'==arguments[1].'+f+')';
            s += (idx < sf.length-1)? '{' : 'return 0';
        });
        s += Array(sf.length).join('}')+';return -1';
        return arr.sort(new Function(s));
    };
    
    0 讨论(0)
提交回复
热议问题