Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort array on nested key

I am using this function to sort an array based on object key:

function keysrt(arr, key, reverse) {
    var sortOrder = 1;
    if(reverse){
        sortOrder = -1;
    }
    return arr.sort(function(a, b) {
        var x = a[key],
            y = b[key];

        return sortOrder * ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}   

It works well with this type of array, where key is on the first level:

var a = [ 
    { id: 0, last: 'Anne'},
    { id: 1, last: 'Odine'},
    { id: 2, last: 'Caroline'}
]

keysrt(a, 'last');

How can I make it work with this example, where title key is nested?

var b = [ 
    { id: 0, last: 'Anne',     data:{title: 'habc'}},
    { id: 1, last: 'Odine',    data:{title: 'asdf'}},
    { id: 2, last: 'Prentice', data:{title: 'tzuio'}}
]

keysrt(b, 'title');
like image 368
Toniq Avatar asked Jan 08 '16 16:01

Toniq


2 Answers

For this idea the "key" variable changes into an array of keys: Then you specify the "path" to the nested value you want to sort on.

function keysrt(arr, keyArr, reverse) {
    var sortOrder = 1;
    if(reverse)sortOrder = -1;
    return arr.sort(function(a, b) {
        var x=a,y=b;
        for (var i=0; i < keyArr.length; i++) {
          x = x[keyArr[i]];
          y = y[keyArr[i]];
        }
        return sortOrder * ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
} 

keysrt(b,['data','title']);
like image 110
James Avatar answered Sep 28 '22 02:09

James


If you are ready to change the function signature and the function call, here is a simple solution-

function keysrt(arr, prop, key, reverse) {
    var sortOrder = 1;
    if(reverse)sortOrder = -1;
    return arr.sort(function(a, b) {
        var x = a[prop][key]; var y = b[prop][key];
        return sortOrder * ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}   


var b = [ 
    { id: 0, last: 'Anne',     data:{title: 'habc'}},
    { id: 1, last: 'Odine',    data:{title: 'asdf'}},
    { id: 2, last: 'Prentice', data:{title: 'tzuio'}}
]

keysrt(b,'data', 'title');

Here, prop represents the outer object, key would represent the nested key.

So, var y = b[prop][key] would basically mean you are accessing b.data.title

Hope it helps :) Happy coding!

like image 20
bozzmob Avatar answered Sep 28 '22 04:09

bozzmob