mike hennessy
mike hennessy

Reputation: 1679

How can I use sort expression to dynamically sort on object attribute?

I have an array of objects and I'd like to dynamically sort the list based on a parameter. Here is an example that show's what works and what doensn't work when I try to use parameter.

const field = 'email'
const users = [{Array of users}]
users = users.sort((a, b) => (a.email > b.email? 1 : -1)); << WORKS
users = users.sort((a, b) => (a.['email'] > b['email']? 1 : -1));  << WORKS

users = users.sort((a, b) => (a.[`'${field}'`] > b[`'${field}'`]? 1 : -1));  << DOESN'T WORK

How can I dynamically sort the list based on a defined parameter?

Upvotes: 0

Views: 186

Answers (2)

Wex
Wex

Reputation: 15695

You can actually pass variables directly into the square bracket notation:

users = users.sort((a, b) => a[field] > b[field] ? 1 : -1);

I don't recommend this, but if you did want to use template strings it would look more like this:

a[`${field}`]

If you are sorting by string fields, you'd be better off using localeCompare for your comparison:

users = users.sort((a, b) => { 
  return a[field].toLowerCase().localeCompare(b[field].toLowerCase());
});

I also wanted to point out that for a numeric sort, it's more common to subtract the numbers than to compare them (this is descending order, switch the order to a[field] - b[field] for ascending):

users = users.sort((a, b) => b[field] - a[field]);

A few additional helper functions based on the discussion in the comments:

function stringSort(a, b) {
  return a[field].toLowerCase().localeCompare(b[field].toLowerCase());
}

function numberSort(a, b) {
  return b[field] - a[field];
}

users = users.sort(field === 'email' ? stringSort : numberSort);

Upvotes: 2

Mechanic
Mechanic

Reputation: 5380

this ' is extra in last statement,

users = users.sort((a, b) => (a.[`${field}`] > b[`${field}`]? 1 : -1));  

btw the result of above is the same this one (for demonstration purpose only

users = users.sort((a, b) => a[field.toString()] > b[field.toString()] ? 1 : -1);

so the best way is the one that @wex has already suggested which is to directly put the variable in brackets:

users = users.sort((a, b) => a[field] > b[field] ? 1 : -1);

Upvotes: 0

Related Questions