John Dorean
John Dorean

Reputation: 3874

Ordering a Javascript array by object properties contained in another array

My first array looks like this:

[
    {entityId: 1, name: 'Total sales'},
    {entityId: 2, name: 'Total customers'},
    {entityId: 3, name: 'Reach'}
]

I have a second array which stores entityIds, and I need to sort the first array using the values of the second array. So, if my second array looks like this:

[1, 3, 2]

then my first array should be sorted like this:

[
    {entityId: 1, name: 'Total sales'},
    {entityId: 3, name: 'Reach'},
    {entityId: 2, name: 'Total customers'}
]

I know I can sort an array based on object properties by using the sort method with my own callback:

array.sort(function(a, b) {
    // ... sorting logic ...
});

However I'm struggling to wrap my head around how the sorting logic will follow the sorting rules imposed by the second array, rather than just comparing two neighbouring elements.

Upvotes: 1

Views: 54

Answers (3)

Grundy
Grundy

Reputation: 13381

Yet another variant, possibly better for big array, because iterate over arrays just twice. In case indexOf - iterate twice on every calling sort callback.

first, create map from first array

var array = [
    {entityId: 1, name: 'Total sales'},
    {entityId: 2, name: 'Total customers'},
    {entityId: 3, name: 'Reach'}
];

var map = array.reduce(function(acc,el){
    acc[el.entityId] = el;
    return acc;
},{});

second, just map second array

var indexes = [1, 3, 2];

var result = indexes.map(function(index){ return map[index];});

naive test in jsperf

Upvotes: 1

Asad Palekar
Asad Palekar

Reputation: 301

Simplest code would be:

var a = [
    {entityId: 1, name: 'Total sales'},
    {entityId: 2, name: 'Total customers'},
    {entityId: 3, name: 'Reach'}
];

var b = [1,3,2];
var c = b.slice(); //create copy

for (var i = 0;i< a.length;i++)
{
   var indexOf = b.indexOf(a[i].entityId);

   c[indexOf] = a[i];
}

console.log(c)

try the jsfiddle

Upvotes: -1

Amir Popovich
Amir Popovich

Reputation: 29836

Use Array.prototype.indexOf:

var arr = [
    {entityId: 1, name: 'Total sales'},
    {entityId: 2, name: 'Total customers'},
    {entityId: 3, name: 'Reach'}
];

var indArr = [3, 1, 2];

arr.sort(function(a, b) {
    return indArr.indexOf(a.entityId) - indArr.indexOf(b.entityId);
});

console.log(arr);

JSFIDDLE.

Upvotes: 7

Related Questions