DEV Community

Cover image for JS: Sort an Array of Objects on multiple columns/keys
Mark Dsouza
Mark Dsouza

Posted on

JS: Sort an Array of Objects on multiple columns/keys

Let's see how you can completely configure the sorting of an Array of objects. Let's say we have the below data set for our entire example.



let objs = [
  { name: 'Mark',
    age: 30,
    RollNo: 'R01'
  },
  { name: 'Anne',
    age: 20,
    RollNo: 'R02'
  },
  { name: 'James',
    age: 40,
    RollNo: 'R03'
  },
  { name: 'Jerry',
    age: 30,
    RollNo: 'R04'
  },
  { name: 'Lucy',
    age: 30,
    RollNo: 'R05'
  },
  { name: 'Mark',
    age: 30,
    RollNo: 'R06'
  },
]


Enter fullscreen mode Exit fullscreen mode

Looking at the raw data we have with a console.table(objs)
Table

Single Column Sort

Now say we want to sort this data across one column. The best way to do this is the sort() method. Check out the documentation.
An example from there down below on a simple array of Strings



const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);


Enter fullscreen mode Exit fullscreen mode

The output is ["Dec", "Feb", "Jan", "March"]
This automatically sorts the original array in alphabetical order and returns the original array as well on calling sort().

Sorting on String

Using the above example, let us try and sort our object



objs.sort(function(a, b) {
    return a.name.localeCompare(b.name)
});


Enter fullscreen mode Exit fullscreen mode

Single Sort on Name
This is similar to a SQL Statement



SELECT * FROM OBJS ORDER BY NAME; 


Enter fullscreen mode Exit fullscreen mode

Sorting on number (the ES6 way)

With ES6, we can even write it as an inline function. Let's try and sort based on the number field age.



objs.sort((a, b) => a.age - b.age);


Enter fullscreen mode Exit fullscreen mode

Single Sort on Age
This is similar to a SQL Statement



SELECT * FROM OBJS ORDER BY AGE; 


Enter fullscreen mode Exit fullscreen mode

Multi Column Sort

We can combine sorts using the || operator in the order of the sorting we need.

Sort by Age, and then Name



objs.sort((a,b)=> (a.age - b.age || a.name.localeCompare(b.name)  ));


Enter fullscreen mode Exit fullscreen mode

MultiSort on age and name
This is similar to a SQL Statement



SELECT * FROM OBJS ORDER BY AGE, NAME; 


Enter fullscreen mode Exit fullscreen mode

Sort by Name, and then Age

We can modify the order of how the sort is done. That is if we want to sort by name first and then age



objs.sort((a,b)=> (a.name.localeCompare(b.name) || a.age - b.age));


Enter fullscreen mode Exit fullscreen mode

This is similar to a SQL Statement



SELECT * FROM OBJS ORDER BY NAME, AGE; 


Enter fullscreen mode Exit fullscreen mode

Changing to Descending order

If we wanted Age and Name to be descending order we just need to swap the above command with



objs.sort((a,b)=> (b.age - a.age || b.name.localeCompare(a.name)  ));


Enter fullscreen mode Exit fullscreen mode

MultiSort on age and name Descending
This is similar to a SQL Statement



SELECT * FROM OBJS ORDER BY NAME DESC, AGE DESC; 


Enter fullscreen mode Exit fullscreen mode

Extend to sort on all 3 columns

Using the above logic, you can append how many ever sort columns you might need in the order you need them.



objs.sort((a,b)=> (a.name.localeCompare(b.name) || a.age - b.age || a.RollNo - b.RollNo));


Enter fullscreen mode Exit fullscreen mode

MultiSort on 3 columns
This is similar to a SQL Statement



SELECT * FROM OBJS ORDER BY NAME , AGE , ROLLNO;

Enter fullscreen mode Exit fullscreen mode




Use Case

Say you have an API that returns an Array of Objects in a random manner. Maybe you have a table in your UI and you want to sort this data that comes in such that it makes the most sense for your user(sort on some category or maybe price). All you need to do is tweak the above logic and tada!

Top comments (5)

Collapse
 
jsolano profile image
J.P. Solano

Thank you ! great post, I'll add the use case when have two string columns and need to order. My solution was concat first and then a.localeCompare(b)

Collapse
 
markbdsouza profile image
Mark Dsouza

Ohhhh. At the beginning I thought there might be some edge cases your method might not work really well... but, it surely will get the job done. :D
That is a pretty neat work around !!

Collapse
 
miracolosa profile image
Milagros Lasarte

So I've tried this and the II doesn't work. Only the left side is respected and the other side ignored. It works if I do && šŸ¤”

Collapse
 
hugo_meneses_a8530c590efc profile image
hugo meneses

Muchas Gracias, me gusto tu articulo.

Collapse
 
dhea_fadlia profile image
Dhea Fadlia

such clear and simple explanation, well done!