3

Basically, I'm trying to sort an array of objects by property.

Say I have three objects within an array, each with a property views

var objs = [
    {
        views: '17'
    },
    {
        views: '6'
    },
    {
        views: '2'
    }
];

Using the sort method on the array objs:

function sortByProperty(property) {
    return function (a,b) {
        /* Split over two lines for readability */
        return (a[property] < b[property]) ? -1 : 
               (a[property] > b[property]) ? 1 : 0;
    }
}


objs.sort(sortByProperty('views'));

I expect objs to now be in the reverse order basically, however the '17' seems to be treated as less than '6' and '2'. I realise this is probably because of the '1'.

Any ideas on resolving this problem?

I realise I could iterate through each object and convert to integers - but is there a way to avoid doing that?

JSFiddle: http://jsfiddle.net/CY2uM/

Community
  • 1
  • 1
ahren
  • 16,803
  • 5
  • 50
  • 70

3 Answers3

3

Javascript is somewhat typed language; the < means alphabetical sort for strings, numeric sort for numbers. The only way is to coerce the values into numbers. Unary operator + helps here. Thus try

function sortByNumericProperty(property) {
    return function (a,b) {
        var av = +a[property], bv = +b[property];
        /* Split over two lines for readability */
        return (av < bv) ? -1 : 
               (av > bv) ? 1 : 0;
    }
}

But generally the common idiom (also documented on MDN)

function sortByNumericProperty(property) {
    return function (a,b) {
        return a[property] - b[property];
    }
}

Should also work.

2

if a[property] and b[property] can be parsed to numbers

function sortByProperty(property) {
    return function (a,b) {
            return a[property] - b[property];
    }
}
Diode
  • 24,570
  • 8
  • 40
  • 51
0

You may have to convert your values to integer before using it -

function sortByProperty(property) {
    return function (a,b) {
        var x = parseInt(a[property]);  
        var y = parseInt(b[property])
        /* Split over two lines for readability */
        return (x < y) ? -1 : (x > y) ? 1 : 0;
    }
}
Moazzam Khan
  • 3,130
  • 2
  • 20
  • 35
  • Yeah, I realise I could simply `parseInt` everything - but it's not quite what I was hoping for... – ahren Aug 18 '13 at 16:57