Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ES6 specific method to loop through two arrays and find matches in each?

Let's say I have two arrays of objects that I want to compare:

var arr1 = [
  {
    name: 'A', type: "Dog"
  },
  {
    name: 'B', type: "Zebra"
  },
  {
    name: 'C', type: "Cat"
  },
  {
    name: 'D', type: "Dingo"
  }
]

var arr2 = [
  {
    name: 'A', type: "Wolf"
  },
  {
    name: 'B', type: "Echidna"
  },
  {
    name: 'C', type: "Wallaby"
  },
  {
    name: 'D', type: "Rabbit"
  }
]

Pretend that arr1 is old data, and arr2 is updated data coming from an API.

I want to loop through the arrays, finding objects whose name matches. If there is a match, I want to update the type from arr1 to arr2.

I'd do this like so:

for(var i = 0; i<arr1.length; i++){
  for(var x = 0; x<arr2.length; x++){
    if(arr1[i].name === arr2[x].name){
      arr1[i].type = arr2[x].type;
    }
  }
}

I'm wondering if there are any updated ways in ECMAScript 6 which make this easier to do (in a real world scenario the logic is a lot more complex and looping within a loop feels rather clunky);

like image 365
JVG Avatar asked Mar 14 '23 02:03

JVG


2 Answers

In ES2015 you wouldn't use this data structure, you would use maps:

var map1 = new Map([
  ['A', "Dog"],
  ['B', "Zebra"],
  ['C', "Cat"],
  ['D', "Dingo"]
]);
var map2 = new Map([
  ['A', "Wolf"],
  ['B', "Echidna"],
  ['C', "Wallaby"],
  ['D', "Rabbit"]
]);

And then, to update map1 with the data from map2, you would use

for(let [key, value] of map2)
  map1.set(key, value);

Map operations are required to be sublinear on average. They should be constant if the map is implemented with a hash. Then the total cost would be linear.

Alternatively, since the keys are strings, you can consider using a plain object. You can create it with Object.create(null) to prevent it from inheriting properties from Object.prototype, and assign the properties with Object.assign

var obj1 = Object.assign(Object.create(null), {
  A: "Dog",
  B: "Zebra",
  C: "Cat",
  D: "Dingo"
});
var obj2 = Object.assign(Object.create(null), {
  A: "Wolf",
  B: "Echidna",
  C: "Wallaby",
  D: "Rabbit"
});

And then, to update obj1 with the data from obj2, you would use

for(let key in obj2)
  obj1[key] = obj2[key];

Most probably the object will be implemented using a hash, so each assignment will be constant on average. The total cost would be linear.

like image 81
Oriol Avatar answered Apr 26 '23 21:04

Oriol


You can use a forEach loop (ES5) or the for..of loop from ES6:

for (let item1 of arr1) {
  for (let item2 of arr2) {
    if(item1.name === item2.name){
      item1.type = item2.type;
    }
  }
}

If these lists are quite long I would suggest putting the updated list into a hash map so your time complexity is linear rather than quadratic.

like image 22
Tate Thurston Avatar answered Apr 26 '23 22:04

Tate Thurston