25

Given an array of objects like this:

objects = [
  { id: 'aaaa', description: 'foo' },
  { id: 'bbbb', description: 'bar' },
  { id: 'cccc', description: 'baz' }
];

And an array of strings like this:

order = [ 'bbbb', 'aaaa', 'cccc' ];

How would I sort the first array so that the id attribute matches the order of the second array?

1
  • 2
    What should happen when there is a missing element on any list? Commented Feb 4, 2014 at 11:15

3 Answers 3

49

Try this:

objects.sort(function(a, b){
    return order.indexOf(a.id) - order.indexOf(b.id)
});

Assuming the variables are like you declared them in the question, this should return:

[
    { id: 'bbbb', description: 'bar' },
    { id: 'aaaa', description: 'foo' },
    { id: 'cccc', description: 'baz' }
];

(It actually modifies the objects variable)

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

2 Comments

If there are elements in objects that aren't in the orders array they appear at the top. Is there a way to make those show up at the end of the list instead of the start?
@BarryMichaelDoyle: Yea, you'd need to check both indexOf values for -1, and if they are -1 return Number.MAX_VALUE instead.
2

You need a way to translate the string into the position in the array, i.e. an index-of function for an array.

There is one in newer browsers, but to be backwards compatible you need to add it if it's not there:

if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(str) {
    var i;
    for (i = 0; i < this.length; i++) if (this[i] == str) return i;
    return -1;
  }
}

Now you can sort the array by turning the string into an index:

objects.sort(function(x,y){ return order.indexOf(x.id) - order.indexOf(y.id); });

Demo: http://jsfiddle.net/Guffa/u3CQW/

Comments

0

Use a mapping object for (almost) constant access time:

/* Create a mapping object `orderIndex`:
{
  "bbbb": 0,
  "aaaa": 1,
  "cccc": 2
}
*/
const orderIndex = {}
order.forEach((value, index) => orderIndex[value] = index);

// Sort
objects.sort((a, b) => orderIndex[a.id] - orderIndex[b.id]);

// data
const objects = [
  { id: 'aaaa', description: 'foo' },
  { id: 'bbbb', description: 'bar' },
  { id: 'cccc', description: 'baz' }
];
const order = [ 'bbbb', 'aaaa', 'cccc' ];

/* Create a mapping object `orderIndex`:
{
  "bbbb": 0,
  "aaaa": 1,
  "cccc": 2
}
*/
const orderIndex = {}
order.forEach((value, index) => orderIndex[value] = index);

// Sort
objects.sort((a, b) => orderIndex[a.id] - orderIndex[b.id]);

// Log
console.log('orderIndex:', orderIndex);
console.log('objects:', objects);

Comments

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.