Categories
arrays javascript sorting

Sorting an array of objects by property values

1618

I’ve got the following objects using AJAX and stored them in an array:

var homes = [
    {
        "h_id": "3",
        "city": "Dallas",
        "state": "TX",
        "zip": "75201",
        "price": "162500"
    }, {
        "h_id": "4",
        "city": "Bevery Hills",
        "state": "CA",
        "zip": "90210",
        "price": "319250"
    }, {
        "h_id": "5",
        "city": "New York",
        "state": "NY",
        "zip": "00010",
        "price": "962500"
    }
];

How do I create a function to sort the objects by the price property in ascending or descending order using JavaScript only?

2

2082

Sort homes by price in ascending order:

homes.sort(function(a, b) {
    return parseFloat(a.price) - parseFloat(b.price);
});

Or after ES6 version:

homes.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));

Some documentation can be found here.

For descending order, you may use

homes.sort((a, b) => parseFloat(b.price) - parseFloat(a.price));

12

  • 234

    You can use string1.localeCompare(string2) for string comparison

    – bradvido

    May 27, 2014 at 13:51


  • 84

    Keep in mind that localeCompare() is case insensitive. If you want case sensitive, you can use (string1 > string2) - (string1 < string2). The boolean values are coerced to integer 0 and 1 to calculate the difference.

    May 1, 2015 at 21:58

  • 3

    Thanks for the update, @Pointy, I don’t remember running into this problem, but perhaps the behaviour has changed in the last couple of years. Regardless, the localeCompare() documentation shows that you can explicitly state whether you want case sensitivity, numeric sorting, and other options.

    Aug 28, 2017 at 16:11

  • 4

    @sg28 I think you’ve misunderstood the MDN explanation. It does not say that the sort function is not reliable, it says that it is not stable. I understand why this can be confusing, but that is not a claim that it is not suitable for use. In the context of sorting algorithms, the term stable has a specific meaning – that “equal” elements in the list are sorted in the same order as in the input. This is completely unrelated to the idea of code which is unstable (i.e. not yet ready for use).

    – Stobor

    Jul 30, 2018 at 1:42

  • 3

    If you want to sort by a specific string values for example by city you could use: this.homes.sort((current,next)=>{ return current.city.localeCompare(next.city)});

    Oct 30, 2018 at 4:13

719

Here’s a more flexible version, which allows you to create
reusable sort functions, and sort by any field.

const sort_by = (field, reverse, primer) => {

  const key = primer ?
    function(x) {
      return primer(x[field])
    } :
    function(x) {
      return x[field]
    };

  reverse = !reverse ? 1 : -1;

  return function(a, b) {
    return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
  }
}


//Now you can sort by any field at will...

const homes=[{h_id:"3",city:"Dallas",state:"TX",zip:"75201",price:"162500"},{h_id:"4",city:"Bevery Hills",state:"CA",zip:"90210",price:"319250"},{h_id:"5",city:"New York",state:"NY",zip:"00010",price:"962500"}];

// Sort by price high to low
console.log(homes.sort(sort_by('price', true, parseInt)));

// Sort by city, case-insensitive, A-Z
console.log(homes.sort(sort_by('city', false, (a) =>  a.toUpperCase()
)));

8

  • 7

    nickb – you’re misreading the code. sort_by runs in O(1), and returns a function used by the built-in sort (O(N log N)) to compare items in a list. The total complexity is O(n log n) * O(1) which reduces to O(n log n), or the same as a quick sort.

    Oct 31, 2011 at 7:04

  • 1

    One issue I have with this is that with reverse=false, it will sort numbers as 1,2,3,4… but Strings as z,y,x…

    – Abby

    Apr 26, 2012 at 13:42

  • 4

    A small enhancement: var key = primer ? function (x) { return primer(x[field]); } : function (x) { return x[field]; }

    – ErikE

    Aug 7, 2012 at 1:18

  • 10

    While [1,-1][+!!reverse] looks cool, it’s a horrible thing to do. If a user can’t call your method properly, punish him, not try to somehow make sense of it, no matter what.

    Dec 3, 2013 at 21:28

  • 2

    Wouldn’t it be better to prepare the source data, this would cause consecutive parsing when clearly the source data needs some tweaking.

    Mar 5, 2015 at 14:14

149

To sort it you need to create a comparator function taking two arguments. Then call the sort function with that comparator function as follows:

// a and b are object elements of your array
function mycomparator(a,b) {
  return parseInt(a.price, 10) - parseInt(b.price, 10);
}
homes.sort(mycomparator);

If you want to sort ascending switch the expressions on each side of the minus sign.

2