最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ES6 specific method to loop through two arrays and find matches in each? - Stack Overflow

programmeradmin4浏览0评论

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

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 ing 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 plex and looping within a loop feels rather clunky);

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

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 ing 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 plex and looping within a loop feels rather clunky);

Share Improve this question edited Mar 1, 2016 at 0:30 miken32 42.8k16 gold badges125 silver badges174 bronze badges asked Feb 29, 2016 at 23:41 JVGJVG 21.2k48 gold badges141 silver badges216 bronze badges 4
  • Array.prototype.find or findIndex – zerkms Commented Feb 29, 2016 at 23:50
  • Will all objects have different names? – Oriol Commented Feb 29, 2016 at 23:57
  • @Oriol Yes, the name is a unique identifier. Sometimes arr2 will introduce names that weren't in arr1, which will need to be inserted. – JVG Commented Mar 1, 2016 at 0:00
  • 1 If name is a unique identifier, then you should probably use those as keys in an object so you always have constant time lookup as opposed to having to iterate through two arrays to find matches. – user5004821 Commented Mar 1, 2016 at 0:10
Add a ment  | 

2 Answers 2

Reset to default 5

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.

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 plexity is linear rather than quadratic.

发布评论

评论列表(0)

  1. 暂无评论