How to sort a JavaScript array of objects by nested object property?

后端 未结 8 1825
广开言路
广开言路 2020-12-01 06:37

I have this function to sort a JavaScript array of objects based on a property:

// arr is the array of objects, prop is the property to sort by
var sort = fu         


        
相关标签:
8条回答
  • 2020-12-01 06:42

    This is my modify code.

    // arr is the array of objects, prop is the property to sort by
    var s = function (prop, arr) {
        // add sub function for get value from obj (1/2)
        var _getVal = function(o, key){
            var v = o;
            var k = key.split(".");
            for(var i in k){
                v = v[k[i]];
            }
            return v;
        }
        return arr.sort(function (a, b) {
            // get value from obj a, b before sort (2/2)
            var aVal = _getVal(a, prop);
            var bVal = _getVal(b, prop);
            if (aVal < bVal) {
                return -1;
            } else if (aVal > bVal) {
                return 1;
            } else {
                return 0;
            }
        });
    };
    
    0 讨论(0)
  • 2020-12-01 06:43

    Instead of passing the property as a string, pass a function that can retrieve the property from the top level object.

    var sort = function (propertyRetriever, arr) {
        arr.sort(function (a, b) {
            var valueA = propertyRetriever(a);
            var valueB = propertyRetriever(b);
    
            if (valueA < valueB) {
                return -1;
            } else if (valueA > valueB) {
                return 1;
            } else {
                return 0;
            }
        });
    };
    

    Invoke as,

    var simplePropertyRetriever = function(obj) {
        return obj.property;
    };
    
    sort(simplePropertyRetriever, { .. });
    

    Or using a nested object,

    var nestedPropertyRetriever = function(obj) {
        return obj.nestedObj.property;
    };
    
    sort(nestedPropertyRetriever, { .. });
    
    0 讨论(0)
  • 2020-12-01 06:49

    if you have array of objects like

    const objs = [{
            first_nom: 'Lazslo',
            last_nom: 'Jamf',
            moreDetails: {
                age: 20
            }
        }, {
            first_nom: 'Pig',
            last_nom: 'Bodine',
            moreDetails: {
                age: 21
            }
        }, {
            first_nom: 'Pirate',
            last_nom: 'Prentice',
            moreDetails: {
                age: 22
            }
        }];
    

    you can use simply

    nestedSort = (prop1, prop2 = null, direction = 'asc') => (e1, e2) => {
            const a = prop2 ? e1[prop1][prop2] : e1[prop1],
                b = prop2 ? e2[prop1][prop2] : e2[prop1],
                sortOrder = direction === "asc" ? 1 : -1
            return (a < b) ? -sortOrder : (a > b) ? sortOrder : 0;
        }
    

    and call it

    for direct objects

    objs.sort(nestedSort("last_nom"));
    objs.sort(nestedSort("last_nom", null, "desc"));
    

    for nested objects

    objs.sort(nestedSort("moreDetails", "age"));
    objs.sort(nestedSort("moreDetails", "age", "desc"));
    
    0 讨论(0)
  • 2020-12-01 06:54

    You can use Agile.js for this kind of things.
    Actually you pass an expression instead of callback, it's handle nested properties and javascript expression in a very nice-ish way.

    Usage: _.orderBy(array, expression/callback, reverse[optional])

    Example:

    var orders = [
      { product: { price: 91.12, id: 1 }, date: new Date('01/01/2014') },
      { product: { price: 79.21, id: 2 }, date: new Date('01/01/2014') },
      { product: { price: 99.90, id: 3 }, date: new Date('01/01/2013') },
      { product: { price: 19.99, id: 4 }, date: new Date('01/01/1970') }
    ];
    
    _.orderBy(orders, 'product.price');
    // →  [orders[3], orders[1], orders[0], orders[2]]
    
    _.orderBy(orders, '-product.price');
    // → [orders[2], orders[0], orders[1], orders[3]]
    
    0 讨论(0)
  • 2020-12-01 06:54

    Would this meet your needs?

    // arr is the array of objects, prop is the property to sort by
    var sort = function (nestedObj, prop, arr) {
        arr.sort(function (a, b) {
            if (a[nestedObj][prop] < b[nestedObj][prop]) {
                return -1;
            } else if (a[nestedObj][prop] > b[nestedObj][prop]) {
                return 1;
            } else {
                return 0;
            }
        });
    };
    
    0 讨论(0)
  • 2020-12-01 06:59

    You can split the prop on ., and iterate over the Array updating the a and b with the next nested property during each iteration.

    Example: http://jsfiddle.net/x8KD6/1/

    var sort = function (prop, arr) {
        prop = prop.split('.');
        var len = prop.length;
    
        arr.sort(function (a, b) {
            var i = 0;
            while( i < len ) { a = a[prop[i]]; b = b[prop[i]]; i++; }
            if (a < b) {
                return -1;
            } else if (a > b) {
                return 1;
            } else {
                return 0;
            }
        });
        return arr;
    };
    
    0 讨论(0)
提交回复
热议问题