2016-11-21 170 views
0

我有合併2個陣列,鍵值如下:深合併嵌套陣列

array1 = [ 
{id:"123", data:[{id:"234",data:"hello"},{id:"345",data:"there"},{id:"xyz", data:"yo"}]}, 
{id:"456", data:[{id:"34",data:"test"},{id:"45",data:"test2"},{id:"yz", data:"test3"}]}, 
{id:"789", data:[{id:"23",data:"aaa"},{id:"34",data:"bbb"},{id:"xy", data:"ccc"}]}] 

array2 = [ 
{id:"456", data:[{id:"45",data:"changed"},{id:"yz", data:"data"}]}, 
{id:"789", data:[{id:"456",data:"appended data"}]}, 
{id:"890", data:[{id:"456",data:"new data"}]}] 

產生類似

merged = [ 
{id:"123", data:[{id:"234",data:"hello"},{id:"345",data:"there"},{id:"xyz", data:"yo"}]}, 
{id:"456", data:[{id:"34",data:"test"},{id:"45",data:"changed"},{id:"yz", data:"data"}]}, 
{id:"789", data:[{id:"23",data:"aaa"},{id:"34",data:"bbb"},{id:"xy", data:"ccc"},{id:"456",data:"appended data"}]}, 
{id:"890", data:[{id:"456",data:"new data"}]}] 

我一直在努力這已經持續了相當長的時間,並且無法獲得滿足該方案的解決方案。大多數解決方案只是進行盲合併,而不是基於id值。嘗試使用lodash mergeWith但沒有得到所需的輸出。拉姆達解決方案也是可以接受的。

感謝,

+2

你已經嘗試了一些時間,讓您分享試了一下 –

+0

它是否幫助你的任何可能性......請讓你知道什麼工作 – Geeky

回答

0

最後,這對我來說是什麼工作。由於@Geeky的顯示方式:

function mergeArrays(arr1, arr2) { 
    var arr3, arrIdx = []; 
    if (!arr1 || arr1.length ==0) return arr2 
    for (var i in arr1) { 
    var shared = false; 
    for (var j in arr2) 
     if (arr2[j].id == arr1[i].id) { 
     shared = true; 
     joined = _.mergeWith({},arr1[i],arr2[j], function (a,b) { 
      if (_.isArray(a)) return b.concat(a)}) 
     arr3.push(joined); 
     break; 
     } 
    if (!shared) { 
     arr3.push(arr1[i]); 
    } 
    } 
    for (var k in arr2) { 
    if (arrIdx[k] !=k) arr3.push(arr2[k]) 
    } 
    return arr3 

} 
0

此鏈接可能會對你有所幫助merge two arrays。我試圖找到set1和set2之間的共同對象,如果有任何我找到獨特的屬性,並改變它們的內容,也在對象2中不存在的屬性,並推動它到object1

請檢查以下代碼段。

var arr1 = [{ 
 
    id: "123", 
 
    data: [{ 
 
    id: "234", 
 
    data: "hello" 
 
    }, { 
 
    id: "345", 
 
    data: "there" 
 
    }, { 
 
    id: "xyz", 
 
    data: "yo" 
 
    }] 
 
}, { 
 
    id: "456", 
 
    data: [{ 
 
    id: "34", 
 
    data: "test" 
 
    }, { 
 
    id: "45", 
 
    data: "test2" 
 
    }, { 
 
    id: "yz", 
 
    data: "test3" 
 
    }] 
 
}, { 
 
    id: "789", 
 
    data: [{ 
 
    id: "23", 
 
    data: "aaa" 
 
    }, { 
 
    id: "34", 
 
    data: "bbb" 
 
    }, { 
 
    id: "xy", 
 
    data: "ccc" 
 
    }] 
 
}] 
 

 
var arr2 = [{ 
 
    id: "456", 
 
    data: [{ 
 
    id: "45", 
 
    data: "changed" 
 
    }, { 
 
    id: "yz", 
 
    data: "data" 
 
    }] 
 
}, { 
 
    id: "789", 
 
    data: [{ 
 
    id: "456", 
 
    data: "appended data" 
 
    }] 
 
}, { 
 
    id: "890", 
 
    data: [{ 
 
    id: "456", 
 
    data: "new data" 
 
    }] 
 
}] 
 
var arr3 = []; 
 
for (var i in arr1) { 
 
    var shared = false; 
 
    for (var j in arr2) 
 
    if (arr2[j].id == arr1[i].id) { 
 
     shared = true; 
 
     // arr1[i].data.concat(arr2[j].data); 
 
     var set1 = pushproperties(arr1[i].data, arr2[j].data); 
 
     arr1[i].data = set1; 
 
     arr3.push(arr1[i]); 
 
     break; 
 
    } 
 
    if (!shared) { 
 
    arr3.push(arr1[i]); 
 
    arr3.push(arr2[j]); 
 
    } 
 

 
} 
 

 
function pushproperties(set1, set2) { 
 
    var filtered = false; 
 
    set2.forEach(function(item) { 
 
    filtered = set1.every(function(element) { 
 
     return element.id != item.id; 
 

 
    }); 
 
    if (filtered) { 
 
     set1.push(item); 
 
    } 
 

 
    }); 
 

 
    set1.forEach(function(item) { 
 
    set2.forEach(function(element) { 
 
     if (item.id == element.id) { 
 
     item.data = element.data; 
 
     } 
 

 
    }); 
 

 

 
    }); 
 

 
    return set1; 
 

 
} 
 

 
console.log(arr3);

希望這有助於

+0

感謝這個。這似乎更接近我所需要的,它幾乎....工作。幾個問題: –

+0

感謝您的這一點。這似乎更接近我所需要的,它幾乎....工作。幾個問題:1.如果數組2只有1個項目與數組1的第2項匹配,那麼我將同時將數組2對象和合並對象推入到arr 3中。
我註釋掉了arr3.push (arr2 [j])來解決這個問題,但是如果arr 2與arr1沒有任何匹配的話,那麼arr2對象不會被推入arr3 –

0

此一功能的合併2個陣列遞歸使用Array.prototype.reduce()。如果它遇到具有相同ID的項目,並且他們有一個data prop,它是一個數組,它使用邏輯將它們合併。如果data不是一個數組,它會被最後一項覆蓋。使用MapMap.prototype.values()array spread

function mergeArraysDeep(arr1, arr2) { 
 
    var unique = arr1.concat(arr2).reduce(function(hash, item) { 
 
    var current = hash[item.id]; 
 
    
 
    if(!current) { 
 
     hash[item.id] = item; 
 
    } else if (Array.isArray(current.data)) { 
 
     current.data = mergeArraysDeep(current.data, item.data); 
 
    } else { 
 
     current.data = item.data; 
 
    } 
 

 
    return hash; 
 
    }, {}); 
 

 
    return Object.keys(unique).map(function(key) { 
 
    return unique[key]; 
 
    }); 
 
} 
 

 
var array1 = [ 
 
    {id:"123", data:[{id:"234",data:"hello"},{id:"345",data:"there"},{id:"xyz", data:"yo"}]}, 
 
    {id:"456", data:[{id:"34",data:"test"},{id:"45",data:"test2"},{id:"yz", data:"test3"}]}, 
 
    {id:"789", data:[{id:"23",data:"aaa"},{id:"34",data:"bbb"},{id:"xy", data:"ccc"}]} 
 
]; 
 

 
var array2 = [ 
 
    {id:"456", data:[{id:"45",data:"changed"},{id:"yz", data:"data"}]}, 
 
    {id:"789", data:[{id:"456",data:"appended data"}]}, 
 
    {id:"890", data:[{id:"456",data:"new data"}]} 
 
]; 
 

 
var result = mergeArraysDeep(array1, array2) 
 

 
console.log(result);

ES6版本:

const mergeArraysDeep = (arr1, arr2) => { 
 
    return [...arr1.concat(arr2).reduce((hash, item) => { 
 
    const current = hash.get(item.id); 
 
    
 
    if(!current) { 
 
     hash.set(item.id, item); 
 
    } else if (Array.isArray(current.data)) { 
 
     current.data = mergeArraysDeep(current.data, item.data); 
 
    } else { 
 
     current.data = item.data; 
 
    } 
 

 
    return hash; 
 
    }, new Map()).values()]; 
 
} 
 

 
const array1 = [ 
 
    {id:"123", data:[{id:"234",data:"hello"},{id:"345",data:"there"},{id:"xyz", data:"yo"}]}, 
 
    {id:"456", data:[{id:"34",data:"test"},{id:"45",data:"test2"},{id:"yz", data:"test3"}]}, 
 
    {id:"789", data:[{id:"23",data:"aaa"},{id:"34",data:"bbb"},{id:"xy", data:"ccc"}]} 
 
]; 
 

 
const array2 = [ 
 
    {id:"456", data:[{id:"45",data:"changed"},{id:"yz", data:"data"}]}, 
 
    {id:"789", data:[{id:"456",data:"appended data"}]}, 
 
    {id:"890", data:[{id:"456",data:"new data"}]} 
 
]; 
 

 
const result = mergeArraysDeep(array1, array2) 
 

 
console.log(result);

+0

感謝你。我試過這種數據的各種組合,但無法讓內部數組合適地合併。 –

+0

你有沒有在答案中試過這個演示? –

+0

是的,我有。我的真實世界的數據有不同的組合,雖然我認爲你的解決方案可以工作,但它並沒有像測試數據那樣合併內部數組 –