In this post, we'll sort an array of objects using Javascript's sort and passing through comparison parameters. This functionality is often misunderstood, yet can be extremely helpful for developers depending on the situation.
Starting off with a list of character names like below, let's sort them based on their age:
const characters = [ { name: 'Tom Sawyer', birthdate: 1876, death: 1945 }, { name: 'Bart Simpson', birthdate: 1989, death: 2017}, { name: 'Holden Caufield', birthdate: 1951, death: 1992 }, { name: 'Tom Joad', birthdate: 1939, death: 1967 }, { name: 'Peter Griffin', birthdate: 1999, death: 2017 } ];
In order to sort the array of objects, we will need to do calculate their age by subtracting the death from the birthdate. We have to explicitly calculate the difference between the two days instead of simply calling sort on the difference between the two days because the function orders items lexicographically (i.e. like a dictionary).
const oldestCharacters = characters.sort(function(a,b) { const lastPerson = a.death - a.birthdate; const nextPerson = b.death - b.birthdate; // we won't return anything yet... });
If you're confused about what happens here, let's break down the loop by inserting a few console.log() statement into the loop. When I add in the following code, I can see which elements are getting compared.
const oldestCharacters = characters.sort(function(a,b) { console.log(a); console.log('----'); console.log(b); console.log(' ----NEXT-----') const lastPerson = a.death - a.birthdate; const nextPerson = b.death - b.birthdate; });
Here is the output provided by chrome. The sort() method behaves differently depending on the browser:
Next, let's discuss the return values from the function. Sort's compare function should always return a number, either positive, negative or 0.
- If the return number is negative, A will be shown before B.
- If the return number is 0, A and B will remain in the same order as when they entered the loop.
- If the return number is positive, B will be shown before A.
Now that we know how return values work, let's add them into our sort mechanism. If the lastPerson is older than the nextPerson, we should return -1. Otherwise, we will return 1.
We'll also append a console.table output to observe the final result of our sorted array.
const oldestCharacters = characters.sort(function(a,b) { const lastPerson = a.death - a.birthdate; const nextPerson = b.death - b.birthdate; if (lastPerson > nextPerson) { return -1; } else { return 1; } }); console.table(oldestCharacters);
This returns a beautifully formatted output of our five characters in the order of their lifespan!
Now that we've got a working block of code, let's think about refactoring it. Whenever I see an if statement with two simple return blocks, I always try to transform that to a ternary operator. It turns out that's super easy to do here, rendering a more eloquent final result.
const oldestCharacters = characters.sort(function(a,b) { const lastPerson = a.death - a.birthdate; const nextPerson = b.death - b.birthdate; return lastPerson > nextPerson ? -1 : 1; });
For further investigation into how sorting works in Javascript or how to sort a simple array, I recommend diving into the official documentation. Any questions? Feel free to shoot them in the comments below!