DEV Community

Cover image for How to create a custom sort order in javascript
Aaron
Aaron

Posted on β€’ Originally published at afewminutesofcode.com

15 6

How to create a custom sort order in javascript

image from undraw.co

Originally posted on afewminutesofcode.com

Usually we will want to sort an array numerically or in alphabetical order, but there are also some cases were we might need a custom sort order.

Take the below example we want to show the items inProgress first, then todo and then done.

const tasks = [
  {id:1, title: 'Job A', status: 'done'},
  {id:2, title: 'Job B', status: 'inProgress'},
  {id:3, title: 'Job C', status: 'todo'},
  {id:4, title: 'Job D', status: 'inProgress'},
  {id:5, title: 'Job E', status: 'todo'}
]

We will first create an array with our desired sort order.

const sortBy = ['inProgress', 'todo', 'done']

Then we will make a function using reduce that will output the data as an object. {inProgress: 0, todo: 1, done: 2} with the array item as the key and the index as the value.

const sortByObject = data => data.reduce(
  (obj,item,index) => ({
    ...obj,
    [item]:index
}), {}
)
console.log(sortByObject(sortBy))
/* {inProgress: 0, todo: 1, done: 2} */

Now we have our sorting setup we can bring it all together with a reusable function that passes in an array (data), a sortby array, and a sortField so we know which field to sort on.

const customSort = ({data, sortBy, sortField}) => {
  const sortByObject = sortBy.reduce(
  (obj, item, index) => ({
      ...obj,
      [item]: index
  }), {})
  return data.sort((a, b) => sortByObject[a[sortField]] - sortByObject[b[sortField]])
}

console.log(customSort({data:tasks, sortBy, sortField: 'status'}))

This will now sort by our custom order, however there will be an issue if there is an item in the list that has a different status (one not in our sort order). So to handle this we will set a default sort field to catch all items we don't want in the sort.

const tasksWithDefault = tasks.map(item => ({...item, sortStatus: sortBy.includes(item.status) ? item.status:'other'}))

With this in place if we log out our function again this time passing in our updated sort field then we now have our correct sort order with other items at the bottom of the list.

console.log(customSort({
  data:tasksWithDefault,
  sortBy: [...sortBy,'other'],
  sortField: 'sortStatus'
  }))

If you are looking for some more tips or want to be notified when my next post is available follow Me Online Here:

Instagram
Facebook
afewminutesofcode.com
Twitter
Pinterest

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

Top comments (2)

Collapse
 
adam_cyclones profile image
Adam Crockett πŸŒ€ β€’

This is how terrifying .sort is and what's being done about it.

v8.dev/blog/array-sort

Collapse
 
afewminutesofcode profile image
Aaron β€’

Thanks for sending this link through, its amazing to see so much going on under the hood that we sometimes take for granted!

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

πŸ‘‹ Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay