21

I have a hard time understanding how to use the array.sort() method to sort an array of objects based on a numeric value found in every object. Essentially I have a scenario of the following form:

var myarray = []
myarray.push({name: "alex", age: 8})
myarray.push({name: "ben", age: 57})
myarray.push({name: "dan", age: 32})

The initial order of the result would be "alex, ben, dan". Now I want to sort this array by age, so the oldest people are first on the list. After sorting the order should be "ben, dan, alex". How do I achieve this in the simplest way possible?

MirceaKitsune
  • 777
  • 1
  • 5
  • 14

4 Answers4

29

You can use destructuring assignment and the .sort method like so:

var myarray = []
myarray.push({name: "alex", age: 8})
myarray.push({name: "ben", age: 57})
myarray.push({name: "dan", age: 32});

var res = myarray.sort(({age:a}, {age:b}) => b-a);
console.log(res);

Or, if you don't feel comfortable with destructing, you can use regular dot notation to access the age property:

var myarray = []
myarray.push({name: "alex", age: 8})
myarray.push({name: "ben", age: 57})
myarray.push({name: "dan", age: 32});

var res = myarray.sort((a, b) => b.age-a.age);
console.log(res);

The way .sort works is defined by what you return from the callback function you pass in. If you return:

  • <= -1 then a will come before b.
  • 0 then keep a and b in the same positions
  • >= 1 then b will come before a

Thus, by calculating the difference between the two ages, this "naturally" gives the correct values to properly sort your array.

Community
  • 1
  • 1
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
  • 1
    This has the incorrect output - it should be `ben`, `dan`, `alex` as shown in the question. – Jack Bashford Feb 11 '19 at 02:17
  • 3
    I think destructing adds an unnecessary level of complexity for newbies. age => age.b - age.a makes it a lot easier to read. – Adrian Brand Feb 11 '19 at 02:50
  • @AdrianBrand yeah, I can see that. I've added an alternative – Nick Parsons Feb 11 '19 at 02:54
  • 1
    **Additional note:** The `.sort()` method does two things, it changes the original array so that it is in sorted order, and it also returns a reference to your original array (which is now sorted). In the above examples `myarray` also becomes sorted. If you don't want `myarray` sorted, you can make a shallow copy of it before you sort: `myarray.slice().sort(...)` – Nick Parsons Mar 22 '22 at 21:55
20

ES6

myarray.sort((a,b) => b.age - a.age)

ES5

myarray.sort(function(a,b){return b.age - a.age})

Detailed description of the sort function can be found here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

*Edited to sort in descending order as OP asked

G_conn
  • 311
  • 3
  • 4
8

Thanks everyone. I solved it by using this option:

data.sort(function(a, b) { return b.score - a.score })
MirceaKitsune
  • 777
  • 1
  • 5
  • 14
  • 3
    This goes descening order. like 9-8-7-6-5-4-3-2-1 for ascending we can use. `a.score - b.score` – Santosh Dec 28 '21 at 08:37
  • Adds some overhead but you can simply `reverse` a descending result: `data.sort(function(a, b) { return b.score - a.score }).reverse()` – vogomatix Nov 29 '22 at 09:07
  • Using `reverse()` unnecessarily increases complexity, simply switch `a` and `b` in the subtraction. – user1438038 Feb 07 '23 at 12:28
5
myarray.sort((a,b) => b.age - a.age)

Is the correct answer but nobody has helped with OP's question of having a hard time understanding sort. The function you pass into sort is the comparison function that when comparing two elements of the array should return less than 0 for a comes first, 0 if they are equal and greater than 0 for b comes first.

I use this default comparer function in my projects

defaultCompare = (a, b) => (!a && !b ? 0 : !a ? -1 : !b ? 1 : a < b ? -1 : a > b ? 1 : 0);

as undefined, null, NaN and other falsey values can throw a spanner in there on you.

Adrian Brand
  • 20,384
  • 4
  • 39
  • 60