2017-10-09 160 views
0

是否可以Concat的两个数组与对象,让第二阵列覆盖第一阵列,他们具有相同的ID:的Javascript CONCAT并覆盖其中元素具有相同的ID

// array 1 
[ 
    {id: 1, name: "foo"}, 
    {id: 2, name: "bar"}, 
    {id: 3, name: "baz"} 
] 

// array 2: 
[ 
    {id: 1, name: "newFoo"}, 
    {id: 4, name: "y"}, 
    {id: 5, name: "z"} 
] 

// out: 
[ 
    {id: 1, name: "newFoo"}, // overwriten by array 2 
    {id: 2, name: "bar"}, // not changed (from array 1) 
    {id: 3, name: "baz"}, // not changed (from array 1) 
    {id: 4, name: "y"}, // added (from array 2) 
    {id: 5, name: "z"} // added (from array 2) 
] 

如果有可能我想做到这一点,而无需使用第三方库

+2

是的,有很多方法可以做到这一点。如果他们的ID匹配,则从第二个元素推入并延伸到第一个元素。否则将数组迭代为一个以id为键并扩展的对象,然后将其转换回数组。 –

+0

好吧,我正在尝试一些东西,你可以给一个例子作为答案? – nusje2000

+0

发布了它作为一个答案... –

回答

1

var a = [ 
 
    {id: 1, name: "foo"}, 
 
    {id: 2, name: "bar"}, 
 
    {id: 3, name: "baz"} 
 
]; 
 

 
var b = [ 
 
    {id: 1, name: "fooboo"}, 
 
    {id: 4, name: "bar"}, 
 
    {id: 5, name: "baz"} 
 
]; 
 

 
/* iterate through each of b, if match found in a, extend with that of a. else push into b ...*/ 
 
b.forEach(m => { 
 
\t var item = a.find(n => n.id === m.id); 
 
\t if(item) { return Object.assign(item, m); } 
 
\t a.push(m); 
 
}); 
 

 
console.log(a);

1

你可以做

let arr1 = [ 
 
    {id: 1, name: "foo"}, 
 
    {id: 2, name: "bar"}, 
 
    {id: 3, name: "baz"} 
 
] 
 

 
let arr2 = [ 
 
    {id: 1, name: "newFoo"}, 
 
    {id: 4, name: "y"}, 
 
    {id: 5, name: "z"} 
 
] 
 
let result = arr1.concat(arr2).reduce((a, b) => { 
 
    a[b.id] = b.name; 
 
    return a; 
 
},{}) 
 
result = Object.keys(result).map(e => { 
 
    return {id : e, name : result[e]}; 
 
}); 
 
console.log(result);

说明

我使用他们不守重复键对象的属性,所以对于数组concated在一起,我把它降低到id的对象,因为它的键和名称其价值,因此压倒一切重复。在下一步中,我将其转换回数组。

+1

很好地完成。除了代码之外,你应该提供一个解释。 –

+0

不错的作品@ marvel308。认为我们确实不需要第一个2 Object.assign,因为对于第一个reduce,您传递一个新对象作为初始值,而对于第二个reduce,您可以传递与初始值相同的对象。 –

+0

是啊,使用concat来避免函数冗余 – marvel308

0

检查你我的解决方案。没有“重写”,我只是使用第二个数组作为基础,如果它具有相同的ID,则不写入值。

let a = [ 
 
    {id: 1, name: "foo"}, 
 
    {id: 2, name: "bar"}, 
 
    {id: 3, name: "baz"} 
 
]; 
 

 
let b = [ 
 
    {id: 1, name: "newFoo"}, 
 
    {id: 4, name: "y"}, 
 
    {id: 5, name: "z"} 
 
]; 
 

 
let duplicateId; 
 

 
a.forEach(aitem => { 
 
\t duplicateId = false; 
 
\t b.forEach(bitem => { 
 
    \t if (aitem.id === bitem.id) 
 
    \t duplicateId = true; 
 
    }); 
 
    if (!duplicateId) 
 
    b.push(aitem); 
 
}); 
 

 
console.log(b);

0

也许你可以使用Object.assign和Object.entries实现,让说:

const arr1 = [ 
    {id: 1, name: "foo"}, 
    {id: 2, name: "bar"}, 
    {id: 3, name: "baz"} 
] 

const arr2 = [ 
    {id: 1, name: "newFoo"}, 
    {id: 4, name: "y"}, 
    {id: 5, name: "z"} 
] 

const obj3 = Object.entries(Object.assign({}, ...arr1, arr2)) 
     .map(([prop, value]) => ({[prop]:value})); 

例子:

https://jsfiddle.net/0f75vLka/

0

另一种选择将数组转换为ma p以id作为键,然后合并对象,然后将其转换回数组。

var arr1 = [ 
    {id: 1, name: "foo"}, 
    {id: 2, name: "bar"}, 
    {id: 3, name: "baz"} 
]; 

var arr2 = [ 
    {id: 1, name: "newFoo"}, 
    {id: 4, name: "y"}, 
    {id: 5, name: "z"} 
]; 

function arr2map(arr) { 
    var map = {}; 
    for (var i = 0; i < arr.length; i++) { 
    var item = arr[i]; 
    map[item.id] = item; 
    } 
    return map; 
} 

function map2arr(map) { 
    var arr = []; 
    for (var i in map) { 
    arr.push(map[i]); 
    } 
    return arr; 
} 

var arr1m = arr2map(arr1); 
var arr2m = arr2map(arr2); 
var arr3m = map2arr(Object.assign({}, arr1m, arr2m)); 

//output 
alert(JSON.stringify(arr3m)); 
相关问题