in

3 Neat Tricks For Sorting Arrays of Objects in JavaScript


Working with arrays of objects in JavaScript can be a headache. Comparing arrays of objects is tricky without libraries. But, thankfully, sorting arrays of objects is somewhat easier because of some neat tricks.



1) Sorting By Date Properties

The hard part of sorting arrays of objects is to compare objects without transforming them explicitly. If you transform an array using map() or filter() before sorting, you lose the original array.

Sorting by date properties is a convenient one-liner because comparing dates in JavaScript is easy: subtracting 2 dates returns the difference between the two dates in milliseconds.

const d1 = new Date('2019-06-01');
const d2 = new Date('2018-06-01');
const d3 = new Date('2019-06-01');

d1 - d3; // 0
d1 - d2; // 31536000000
Enter fullscreen mode

Exit fullscreen mode

So if you want to sort by a createdAt property, all you need to do is subtract the values of createdAt in the sort() callback.

const d1 = new Date('2019-06-01');
const d2 = new Date('2018-06-01');
const d3 = new Date('2019-06-01');

const objects = [
  { createdAt: d1, name: 'Test 1' },
  { createdAt: d2, name: 'Test 2' },
  { createdAt: d3, name: 'Test 3' }
];

objects.sort((a, b) => a.createdAt - b.createdAt);

// [ 'Test 2', 'Test 1', 'Test 3' ]
console.log(objects.map(o => o.name));
Enter fullscreen mode

Exit fullscreen mode



2) Using String Conversions

This trick is a bit less useful, but still interesting. Remember that JavaScript converts the array elements to strings before sorting unless you pass a function parameter to sort(). That means you can define a custom toString() function and JavaScript will sort objects by that toString() function as shown below.

class User {
  constructor(name) {
    this.name = name;
  }

  toString() {
    return this.name.length;
  }
}

const arr = [
  new User('333'),
  new User('4444'),
  new User('22')
];

// Sorts users by `name.length`!
// [ Test { name: '22' }, Test { name: '333' }, Test { name: '4444' } ]
arr.sort();
Enter fullscreen mode

Exit fullscreen mode

This approach is limited because you can only define one toString() function for a given class. And, if you want to change the sort order, you need to change each object’s toString() function.

But this approach can be very useful if your object’s toString() function is exactly what you want to sort by.

class User {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  toString() {
    return `${this.lastName}, ${this.firstName}`;
  }
}

const arr = [
  new User('John', 'Smith'),
  new User('Bill', 'Jones'),
  new User('Mike', 'Palmer')
];

// Sort users by "last, first"
arr.sort();
Enter fullscreen mode

Exit fullscreen mode



3) Sorting by Arbitrary Orderings

Suppose you have an array of characters from Star Trek: The Next Generation:

const characters = [
  { firstName: 'Jean-Luc', lastName: 'Picard', rank: 'Captain', age: 59 },
  { firstName: 'Will', lastName: 'Riker', rank: 'Commander', age: 29 },
  { firstName: 'Geordi', lastName: 'La Forge', rank: 'Lieutenant', age: 29 }
];
Enter fullscreen mode

Exit fullscreen mode

Sorting by name or age is easy. But what about sorting by rank? Turns out that’s easy too. Create a map from ranks to numbers, and sort by the difference in ranks as shown below.

const rankOrder = new Map([
  ['Captain', 1],
  ['Commander', 2],
  ['Lieutenant', 3]
]);

characters.sort((a, b) => {
  return rankOrder.get(a.rank) - rankOrder.get(b.rank);
});

// Picard, Riker, La Forge
characters;
Enter fullscreen mode

Exit fullscreen mode



Source: https://dev.to/masteringjs/3-neat-tricks-for-sorting-arrays-of-objects-in-javascript-3lnb

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

GIPHY App Key not set. Please check settings

A simple verification bot for clubs in The Woodlands SS

A tinted overlay that allows one or more elements to be highlighted with react native