0

I want to extend the functionality of this function AngularJS sorting by property.

It basically sorts an array by its child property. But what I want is to make it more generalized, to make it able to sort by any specified nth-grand-child.

The function is

function orderObjectBy(input, attribute) {
    if (!angular.isObject(input)) return input;

    var array = [];
    for(var objectKey in input) {
        array.push(input[objectKey]);
    }

    array.sort(function(a, b){
        a = parseInt(a[attribute]);
        b = parseInt(b[attribute]);
        return a - b;
    });
    return array;
 }

Here's an array which works with this: orderObjectBy(object, 'stat_a')

array = [
    {stat_a:3},
    {stat_a:2},
    {stat_a:5},
]

Here's what I want to work with it: orderObjectBy(object, 'stats.a')

array = [
    {stats:{a: 3}},
    {stats:{a: 2}},
    {stats:{a: 5}},
]

I have no idea how to do it though. The line where it compares

a = parseInt(a[attribute]);

cannot just take stats.a as attribute.

Neither could I figure out how to make it parseInt(a[stats][a])

Note, stats.a example would be merely .split('.').pop() etc but I want a more general approach, that'll work for stats.some.things.a or stats.some.other.things.a ...)

Any guidance how to proceed?

Community
  • 1
  • 1
laggingreflex
  • 32,948
  • 35
  • 141
  • 196

1 Answers1

1

Split the attribute name by "." and explore the object with the attribute name list.

array.sort(function(a,b) {
    a = parseInt(getAttribute(a, attribute);
    b = parseInt(getAttribute(b, attribute);
    return a-b
})


function getAttribute(object,attribute) {
    var o = object;
    var attrs = attribute.split(".")
    for ( var i=0; i<attrs.length; i++) {
        o = o[attrs[i]];
        if (o==null) {
            return null;
        }
    }

    return o;
}
Jaemok Lee
  • 167
  • 4