0

I've looked at all the solutions that only go 1 level deep, but I want to make a generalized solution, a function to which I can pass what inner properties to compare, something like

var array = [
    {grand: {child: {property: 2}}},
    {grand: {child: {property: 1}}},
    {grand: {child: {property: 3}}},
];

var sorted = array.sortBy('grand.child.property');

Like that, generally passing the 'dot.property.notation' as a string.

But I can't figure out a way to do that with Array.sort's comparator function.

Array.prototype.sortBy = function(predicate){
    return this.sort(function(a, b){
        // how to get a[.grand.child.property] from the 
        // parameter string 'grand.child.property'?
    });
};
laggingreflex
  • 32,948
  • 35
  • 141
  • 196
  • Although the duplicate doesn't have the sorting component, the gist of this question revolves around the same idea. – Ja͢ck Jun 29 '14 at 13:39

1 Answers1

1
function getPropertyByPath(obj, path) {
    return path.split('.').reduce(function (val, key) { return val[key]; }, obj);
}

array.sort(function (a, b) {
    var property = 'grand.child.property';
    return getPropertyByPath(a, property) - getPropertyByPath(b, property);
});

This could/should be made more efficient my some memoization technique to avoid the repeated invocation of getPropertyByPath, but I hope it illustrates the idea.

deceze
  • 510,633
  • 85
  • 743
  • 889