Mike Young
Mike Young

Reputation: 321

Two arrays of objects and need to sort one based on the other

I have two arrays of objects like this

var array1 = [
  {
   "key": 0,
   "display": "hide",
  },
  {
   "key": 1,
   "display": "show",
  },
  {
   "key": 2,
   "display": "show",
  },
 ]

var array2 = [
 {
  "key": 1,
  "question": "some text here",
 },
 {
  "key": 0,
  "question": "Different text here",
 },
 {
  "key": 2,
  "question": "Even more different",
 },
]

I need array1 to be reordered to match the order of the keys in array2, not just update the key to match the order but the display value would need to update (so move/reorder the whole object)

For example after sorting array1 to match the order of array2 keys I'd expected array1 to result in:

[
 {
  "key": 1,
  "display": "show",
 },
 {
  "key": 0,
  "display": "hide",
 },
 {
  "key": 2,
  "display": "show",
 }
]

I know it's probably done using the sort function but I'm having a hard time understanding how it would work in this case.

Upvotes: 2

Views: 76

Answers (3)

Faly
Faly

Reputation: 13346

You can achieve this by:

var array1 = [ { "key": 0, "display": "hide", }, { "key": 1, "display": "show", }, { "key": 2, "display": "show", }];
var array2 = [ { "key": 1, "question": "some text here", }, { "key": 0, "question": "Different text here", }, { "key": 2, "question": "Even more different", }];

var keys = array2.map(el => el.key);
array1.sort((a, b) => keys.indexOf(a.key) - keys.indexOf(b.key));
console.log(array1);

Upvotes: 2

Rajesh
Rajesh

Reputation: 24915

You can create a hashMap, that will hold index values and based on it, you can sort array.

var array1 = [ { "key": 0, "display": "hide", }, { "key": 1, "display": "show", }, { "key": 2, "display": "show", },]

var array2 = [ { "key": 1, "question": "some text here", }, { "key": 0, "question": "Different text here", }, { "key": 2, "question": "Even more different", },]

var array2Hash = array2.reduce(function(p,c,i){
  p[c.key] = i;
  return p;
}, Object.create(null))

array1.sort(function(a,b){
  return array2Hash[a.key] - array2Hash[b.key];
});

console.log(array1);

Upvotes: 2

T.J. Crowder
T.J. Crowder

Reputation: 1073968

I'd probably approach it by building a map of the keys to indexes of the first array, then using that map when sorting the second, see comments:

var array1 = [ { "key": 0, "display": "hide", }, { "key": 1, "display": "show", }, { "key": 2, "display": "show", },]

var array2 = [ { "key": 1, "question": "some text here", }, { "key": 0, "question": "Different text here", }, { "key": 2, "question": "Even more different", },]

// Build the map of key->index from the first array
var map = Object.create(null);
array1.forEach(function(entry, index) {
  map[entry.key] = index;
});
// Sort the second array using the key->index map
// map[left.key] - map[right.key] returns a number less than 0
// if the left should be before the right, 0 if they're the
// the same (they won't be, as these are indexes from the
// first array), or greater than zero if the left should be
// after the right
array2.sort(function(left, right) {
  return map[left.key] - map[right.key];
});
console.log(array2);
.as-console-wrapper {
  max-height: 100% !important;
}

Upvotes: 1

Related Questions