JS Sort by specific sort order

2019-08-21 07:34发布

问题:

I need to sort my data by a specific order as shown below.

const sortBy = ['b','a','c','e','d']
const data = ['a','d','e']

I know how to sort by asscending/descending

console.log(data.sort((a, b) => a > b)) //["a", "d", "e"]
console.log(data.sort((a, b) => a < b)) //["e", "d", "a"]

But is it possible using .sort to sort in a specific order? eg below my desired order is sortBy

I am currently getting this to work by creating an array of common items between my sort array and my data.

const commonItems = getCommonItemsInArrays(sortBy,data)
console.log(commonItems.map(item => item)) //["a", "e", "d"]

function getCommonItemsInArrays(array1,array2){
  return array1.filter(n => array2.indexOf(n) >= 0)
}

This seems to be working ok but I was wondering if there was a way to handle this via sort?

回答1:

Your .sort() callback can do whatever it needs to do to figure out whether any given item should be before or after any other given item. So it can look up the index of the current item within your sortBy array and proceed accordingly:

const sortBy = ['b','a','c','e','d']
const data = ['a','d','e']

console.log( data.sort((a,b) => sortBy.indexOf(a) - sortBy.indexOf(b)) )

Calling .indexOf() multiple times during the sort would be kind of inefficient though, so you might want to turn you sortBy into an object before you start:

const sortBy = ['b','a','c','e','d']
const data = ['a','d','e']

const sortByObject = sortBy.reduce((a,c,i) => {
  a[c] = i
  return a
}, {})

console.log( data.sort((a,b) => sortByObject[a] - sortByObject[b]) )

(Note that the sort callback is not supposed to return a boolean value.)