2016-02-29 8 views
3

比方说,我有我想要比较对象的两个数组:ES6特定方法循环两个数组并在每个数组中找到匹配项?

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" 
    } 
] 

假装arr1是旧数据,并arr2更新数据从一个API来。

我想循环遍历数组,找到name匹配的对象。如果有匹配,我想将typearr1更新为arr2。如果在ECMAScript中6任何更新的方式使这个容易做到(在真实的场景中的逻辑是一个很大的

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; 
    } 
    } 
} 

我想知道:

我会做到这一点,像这样在循环内复杂和循环感觉相当笨拙);

+0

['Array.prototype.find'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)或'findIndex' – zerkms

+0

所有对象是否都有不同的名字? – Oriol

+0

@Oriol是的,'name'是一个唯一的标识符。有时'arr2'会引入不在'arr1'中的名字,这将需要插入。 – Jascination

回答

1

您可以使用foreach循环(ES5)或for..of循环从ES6:

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

如果这些名单很长,我建议把更新的列表到一个哈希地图,这样你的时间复杂性是线性的而不是二次的。

5

在ES2015你不会使用这种数据结构,你可以使用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"] 
]); 

,然后从map2更新map1的数据,你会使用

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

地图操作要求平均为次线性。如果地图是用散列实现的,它们应该是常量。那么总成本将是线性的。

或者,由于键是字符串,因此可以考虑使用普通对象。你可以用Object.create(null)创建它,防止它从Object.prototype继承属性,并与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" 
}); 

分配的属性,然后,从obj2更新obj1的数据,你会使用

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

很可能对象将使用散列来实现,因此每个赋值平均值将保持不变。总成本将是线性的。

+0

即使在一个更复杂的对象数组? (真实世界的数据有更多的键和值)。这个问题比尝试应用于我自己的用例更粗略/通用,但我对这里的真实世界中的工作也很感兴趣。 – Jascination

+2

@Jascination是的,为什么不呢?平均地图操作必须是次线性的,所以这是一个很好的选择。或者,因为键是字符串,所以旧的'Object.create(null)'将是一个很好的选择。 – Oriol

+0

我认为你需要添加一个'if(map1.has(key))'/ if if(key in obj2)'条件来准确满足OP的要求 – Bergi

相关问题