How to sort an array of objects by multiple fields?

后端 未结 30 2846
北恋
北恋 2020-11-21 11:34

From this original question, how would I apply a sort on multiple fields?

Using this slightly adapted structure, how would I sort city (ascending) & then price (

30条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-21 12:08

    Here's another one that's perhaps closer to your idea for the syntax

    function sortObjects(objArray, properties /*, primers*/) {
        var primers = arguments[2] || {}; // primers are optional
    
        properties = properties.map(function(prop) {
            if( !(prop instanceof Array) ) {
                prop = [prop, 'asc']
            }
            if( prop[1].toLowerCase() == 'desc' ) {
                prop[1] = -1;
            } else {
                prop[1] = 1;
            }
            return prop;
        });
    
        function valueCmp(x, y) {
            return x > y ? 1 : x < y ? -1 : 0; 
        }
    
        function arrayCmp(a, b) {
            var arr1 = [], arr2 = [];
            properties.forEach(function(prop) {
                var aValue = a[prop[0]],
                    bValue = b[prop[0]];
                if( typeof primers[prop[0]] != 'undefined' ) {
                    aValue = primers[prop[0]](aValue);
                    bValue = primers[prop[0]](bValue);
                }
                arr1.push( prop[1] * valueCmp(aValue, bValue) );
                arr2.push( prop[1] * valueCmp(bValue, aValue) );
            });
            return arr1 < arr2 ? -1 : 1;
        }
    
        objArray.sort(function(a, b) {
            return arrayCmp(a, b);
        });
    }
    
    // just for fun use this to reverse the city name when sorting
    function demoPrimer(str) {
        return str.split('').reverse().join('');
    }
    
    // Example
    sortObjects(homes, ['city', ['price', 'desc']], {city: demoPrimer});
    

    Demo: http://jsfiddle.net/Nq4dk/2/


    Edit: Just for fun, here's a variation that just takes an sql-like string, so you can do sortObjects(homes, "city, price desc")

    function sortObjects(objArray, properties /*, primers*/) {
        var primers = arguments[2] || {};
    
        properties = properties.split(/\s*,\s*/).map(function(prop) {
            prop = prop.match(/^([^\s]+)(\s*desc)?/i);
            if( prop[2] && prop[2].toLowerCase() === 'desc' ) {
                return [prop[1] , -1];
            } else {
                return [prop[1] , 1];
            }
        });
    
        function valueCmp(x, y) {
            return x > y ? 1 : x < y ? -1 : 0; 
        }
    
        function arrayCmp(a, b) {
            var arr1 = [], arr2 = [];
            properties.forEach(function(prop) {
                var aValue = a[prop[0]],
                    bValue = b[prop[0]];
                if( typeof primers[prop[0]] != 'undefined' ) {
                    aValue = primers[prop[0]](aValue);
                    bValue = primers[prop[0]](bValue);
                }
                arr1.push( prop[1] * valueCmp(aValue, bValue) );
                arr2.push( prop[1] * valueCmp(bValue, aValue) );
            });
            return arr1 < arr2 ? -1 : 1;
        }
    
        objArray.sort(function(a, b) {
            return arrayCmp(a, b);
        });
    }
    

提交回复
热议问题