我必须将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,但没有得到所需的输出。 Ramda解决方案也是可以接受的。
谢谢,
答案 0 :(得分:0)
此链接可能对您有所帮助merge two arrays。
在这个代码片段中,我试图找到set1和set2之间的公共对象,如果有任何我找到了唯一的属性并更改了它们的内容以及object2中不存在的属性并将其推送到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);
希望这有帮助
答案 1 :(得分:0)
这个函数使用Array.prototype.reduce()
递归地合并2个数组。如果它遇到具有相同id的项目,并且它们有一个data
prop,它是一个数组,它会使用逻辑合并它们。如果data
不是数组,则会被最后一项覆盖。
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);
使用Map
,Map.prototype.values()
和array spread的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);
答案 2 :(得分: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
}