4

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
  • 3
    "I know how to sort by asscending/descending" - Are you sure? The sort callback isn't supposed to return a boolean value... Anyway, are the data items guaranteed to be in the sortBy array? Commented Oct 17, 2017 at 2:52

1 Answer 1

15

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.)

Sign up to request clarification or add additional context in comments.

4 Comments

I was thinking that it was a pretty contrived example. Your solution sort of works: you pass in a values not on the list, like ['t', 'a','d','p', 'e']. Your code comes back with ["t", "a","e","d"]. If you pass in ["t","a","d","p","e"], you get the same thing out!
no the sort order is a,e,d so the initial test is ok,
@RobertMoskal - If the array being sorted contains values that are not in the sortBy array then I should think by definition the result of the sort is undefined, but the result would still have the same number of items in the array. But as I said in my first sentence, you'd code the sort callback to do whatever was necessary for your sort rules. The OP didn't say what to do for values not in sortBy, but you could add an if/else or whatever to default back to alphabetic sort for unknown values.
No big criticism on my part. It's sort of a strange scenario,

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.