3

I am trying to sort a JavaScript array based on sort order in a second array. I have already gone through other similar questions here in SO and came up with the below code. Be the output is not getting as expected.

var legends = ["Maths","Physics","English","French","Chemistry"];
var sortOrder = [1,400,300,200,-3];

legends.sort( function (a, b) {
    return sortOrder[legends.indexOf(a)] >= sortOrder[legends.indexOf(b)];   
  });


console.log(legends);

The desired output is

["Chemistry", "Maths", "French", "English", "Physics"];
  • Chemistry denotes the sort order -3
  • Maths next higher count, that is 1
  • French next higher count, that is 200

I am trying to get the desired output either in pure JS or using D3js, not sure if I am doing it right!

3 Answers 3

3

You are almost right but in the sort function, you refer to legends array which is being mutated, so indexes does not match to original order.

To demonstrate that this is the case, you could copy the array and sort the copy:

var legends = ["Maths","Physics","English","French","Chemistry"];
var legendsToSort = ["Maths","Physics","English","French","Chemistry"];

var sortOrder = [1,400,300,200,-3];

legendsToSort.sort( function (a, b) {
    return sortOrder[legends.indexOf(a)] >= sortOrder[legends.indexOf(b)];   
  });


console.log(legendsToSort);

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

5 Comments

very funny. just to mention a possible drawback of this.
not being funny here, I thank you for pointing out this problem. I just wanted to help OP understand why his method wasn't working, not to give a better solution
@Francesco sort values are not unique, it can be like [1,5,5,4,-3] and legends will be unique as it will be plotted in a graph. But the point as you mentioned is, my array array was getting mutated.
@NinaScholz its a good point, but my legends array will not have duplicates.
Accepted the answer, but unable to upvote due to low reputation ;(
3

You could take a helper array with indices, sort them and map the wanted array.

var legends = ["Maths", "Physics", "English", "French", "Chemistry"],
    sortOrder = [1, 400, 300, 200, -3];

legends = [...legends.keys()]
    .sort((a, b) => sortOrder[a] - sortOrder[b])
    .map(i => legends[i]);        

console.log(legends);

1 Comment

It helped, wish I could upvote, but unable due to low reputation, new here ;)
1

Try following

var legends = ["Maths","Physics","English","French","Chemistry"];
var sortOrder = [1,400,300,200,-3];

/* Create an array of objects of value index of sortOrder */
legends = Object.entries(sortOrder.reduce((a,v,i) => Object.assign(a, {[v]:i}), {}))
.sort((a,b) => a[0] - b[0]) // Sort array based on sortOrder values
.map(([s, i]) => legends[i]); // fetch items from legends based on sorted order 

console.log(legends);

1 Comment

Thanks for your time, wish I could upvote, but unable due to low reputation, new here ;)

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.