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
orfindIndex
– 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. Sometimesarr2
will introduce names that weren't inarr1
, 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
2 Answers
Reset to default 5In 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.