5

I have two arrays containing objects. One contains keys in some order and another has data and I need to sort the data array in order against the given sorted key array. How can I do this?

var a = ['d','a','b','c'] ;
var b =  [{a:1},{c:3},{d:4},{b:2}];

The result should be:

result = [{d:4},{a:1},{b:2},{c:3]
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
A.T.
  • 24,694
  • 8
  • 47
  • 65

5 Answers5

10

Try this

var a = ['d','a','b','c'] ;
var b =  [{a:1},{c:3},{d:4},{b:2}];

b.sort(function(x,y){
  var xkey = a.indexOf(Object.keys(x)[0]);
  var ykey = a.indexOf(Object.keys(y)[0]);
  return xkey - ykey;
})

document.body.innerHTML += JSON.stringify(b,0,4);
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
5

A different approach from above ones would be, using Lodash Javascript Library.

var a = ['d','a','b','c'] ;
var b =  [{a:1},{c:3},{d:4},{b:2}];

var results = _.map(a,function(av) {
   var obj = {};
   obj[av] = _.find(b, av)[av];
   return obj
});

document.body.innerHTML += JSON.stringify(results);
<script src="https://cdn.jsdelivr.net/lodash/4.11.1/lodash.min.js"></script>
Saba
  • 3,418
  • 2
  • 21
  • 34
1

This approach respects the keys in the objects of the array for sorting.

Only the items of a are used for lookup and their respective order.

In this case d gets all sort value of the item of b, so d looks like

[ 1, 3, 0, 2 ]

While sorting with indices, we need e, which has simply the indices of b

[ 0, 1, 2, 3 ]

after sorting it became

[ 2, 0, 3, 1 ]

the wanted sort order. Now the original array is remapped to the new order.

But why?

Usually objects contains more than one property. If you use Object.keys and take just the first element, then you could go wrong, because this element is not the wanted element for getting the sort order.

To make it save, you need a different approach, which does not use Array#indexOf in combination with a fixed item of Object.keys.

var a = ['d', 'a', 'b', 'c'],
    b = [{ a: 1 }, { c: 3 }, { d: 4 }, { b: 2 }],
    d = b.map(function (bb) {
        var k = -1;
        a.some(function (aa, i) {
            if (aa in bb) {
                k = i;
                return true;
            }
        });
        return k;
    }),
    e = b.map(function (_, i) { return i; });

e.sort(function (a, b) {
    return d[a] - d[b];
});

b = e.map(function (a) {
    return b[a];
});

document.write('<pre> ' + JSON.stringify(b, 0, 4) + '</pre>');
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Brute force approach is to loop through each of a array and check the b array for it's presence.

var a = ['d','a','b','c'] ;
var b =  [{a:1},{c:3},{d:4},{b:2}];

var ans = [];

for(var i = 0; i < a.length; ++i)
{
 for(var j = 0; j < b.length; ++j)
 {
   if(b[j][a[i]])
     ans.push(b[j]);
 }
}
document.write(JSON.stringify(ans, 0, 4));
Uma Kanth
  • 5,659
  • 2
  • 20
  • 41
0

This should do the trick

result = a.map(function(key) {
    for(var i=0; i<b.length; ++i) {
        if(key in b[i]) return b[i];
    }
});
Kulvar
  • 1,139
  • 9
  • 22