2017-10-09 76 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)); 
相關問題