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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.