我想合并这两个对象数组,但对于urls
我想使用unshift来合并数组而不是替换。
这是一个例子
var arr1 = [{
"keyword": "name",
"score": 0.8992112752974006,
"urls": ["url1"],
"ids": ["5748bf9ab58adb2f614da195"]
}, {
"keyword": "name1",
"score": 0.39953909596222775,
"urls": ["url2"],
"ids": ["5743260055f979a31fa98971"]
}, {
"keyword": "name3",
"score": 0.4960953181766197,
"urls": ["url4"],
"ids": ["58c04cd5208b4945c3920cad"]
}, {
"keyword": "name4",
"score": 0.3337163443410707,
"urls": ["url5"],
"ids": ["573628c38e32eeb039377f7e"]
}];
var arr2 = [{
"keyword": "name",
"score": 0.8992112752974006,
"urls": ["url6"],
"ids": [""]
}, {
"keyword": "name1",
"score": 0.39953909596222775,
"urls": ["url7"],
"ids": [""]
}]
我希望结果是
[{
"keyword": "name",
"score": 0.8992112752974006,
"urls": ["url6", "url1"],
"ids": ["5748bf9ab58adb2f614da195"]
}, {
"keyword": "name1",
"score": 0.39953909596222775,
"urls": ["url7", "url2"],
"ids": ["5743260055f979a31fa98971"]
}, {
"keyword": "name3",
"score": 0.4960953181766197,
"urls": ["url4"],
"ids": ["58c04cd5208b4945c3920cad"]
}, {
"keyword": "name4",
"score": 0.3337163443410707,
"urls": ["url5"],
"ids": ["573628c38e32eeb039377f7e"]
}];
这是我的尝试,但结果将取代网址数组;
var a3 = arr1.concat(arr2).reduce((acc, x) => {
acc[x.keyword] = Object.assign(acc[x.keyword] || {}, x);
return acc;
}, {});
console.log(a3);
它将被合并urls
。其他值将被覆盖。
答案 0 :(得分:3)
您可以使用Map
收集具有相同keyword
的对象,并在必要时进行更新。此解决方案适用于任意数组的数组。
var array1 = [{ keyword: "name", score: 0.8992112752974006, urls: ["url1"], ids: ["5748bf9ab58adb2f614da195"] }, { keyword: "name1", score: 0.39953909596222775, urls: ["url2"], ids: ["5743260055f979a31fa98971"] }, { keyword: "name3", score: 0.4960953181766197, urls: ["url4"], ids: ["58c04cd5208b4945c3920cad"] }, { keyword: "name4", score: 0.3337163443410707, urls: ["url5"], ids: ["573628c38e32eeb039377f7e"] }],
array2 = [{ keyword: "name", score: 0.8992112752974006, urls: ["url6"], ids: [""] }, { keyword: "name1", score: 0.39953909596222775, urls: ["url7"], ids: [""] }],
map = new Map,
result = [],
fn = a => {
if (map.has(a.keyword)) {
map.get(a.keyword).urls.unshift(...a.urls);
return;
}
map.set(a.keyword, a);
result.push(a);
};
[array1, array2].forEach(a => a.forEach(fn));
console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:1)
我更喜欢使用Map而不是reduce:
const result = [], hash = new Map();
arr1.concat(arr2).forEach( obj => {
if( hash.has( obj.keyword ) ){
hash.get( obj.keyword ).urls.push(...obj.urls);
}else{
hash.set( obj.keyword, obj);
result.push( obj );
}
});
答案 2 :(得分:0)
在分配给新对象之前,可以将urls
属性从对象中取出,如果不存在则将其添加回来,或者unshift
添加到现有数组中,如果是存在
var arr1 = [{
"keyword": "name",
"score": 0.8992112752974006,
"urls": ["url1"],
"ids": ["5748bf9ab58adb2f614da195"]
}, {
"keyword": "name1",
"score": 0.39953909596222775,
"urls": ["url2"],
"ids": ["5743260055f979a31fa98971"]
}, {
"keyword": "name3",
"score": 0.4960953181766197,
"urls": ["url4"],
"ids": ["58c04cd5208b4945c3920cad"]
}, {
"keyword": "name4",
"score": 0.3337163443410707,
"urls": ["url5"],
"ids": ["573628c38e32eeb039377f7e"]
}];
var arr2 = [{
"keyword": "name",
"score": 0.8992112752974006,
"urls": ["url6"],
"ids": [""]
}, {
"keyword": "name1",
"score": 0.39953909596222775,
"urls": ["url7"],
"ids": [""]
}]
var a3 = arr1.concat(arr2).reduce((acc, x) => {
let urls = x.urls; // store temporarily
delete x.urls; // delete before merging, to not overwrite
acc[x.keyword] = Object.assign(acc[x.keyword] || {}, x);
'urls' in acc[x.keyword] ? [].unshift.apply(acc[x.keyword].urls, urls) : acc[x.keyword].urls = urls;
// ^ if exists unshift or just add
return acc;
}, {});
console.log(a3);
答案 3 :(得分:0)
对于arr1
或arr2
没有任何副作用,您还需要某种克隆。
const a3 = ((a1, a2) => {
const copy = item => {
return {
keyword: item.keyword,
score: item.score,
urls: item.urls.slice(),
ids: item.ids.slice()
};
};
a1 = a1.map(copy);
const dictionary = a1.reduce((acc, item) => {
acc[item.keyword] = item;
return acc;
}, {});
a2.forEach(item => {
if (dictionary[item.keyword]) {
dictionary[item.keyword].urls = item.urls.concat(dictionary[item.keyword].urls);
} else {
const clone = copy(item);
dictionary[clone.keyword] = clone;
a1.push(clone);
}
});
return a1;
})(arr1, arr2);
我用箭头作为函数简写/ const
写了这个,但其余的是ES5
答案 4 :(得分:0)
我使用扩展运算符来合并数组,但unshift()
也可以正常工作。
function mergeObjects(arrayA, arrayB) {
var
// Take all items in arrayA and place them in the result.
result = arrayA.slice(0);
// Iterate over all items in array B
arrayB.forEach(item => {
var
// Check if there is an item in the result with the same keyword.
resultItem = result.find(itemA => itemA.keyword === item.keyword);
// When the keyword isn't yet in the result...
if (resultItem === null) {
// ... add it to the result
result.push(item);
} else {
// ... or else add the urls from the current item to the urls of the result.
resultItem.urls = [...item.urls, ...resultItem.urls];
}
});
// Return the result array.
return result;
}
var arr1 = [{
"keyword": "name",
"score": 0.8992112752974006,
"urls": ["url1"],
"ids": ["5748bf9ab58adb2f614da195"]
}, {
"keyword": "name1",
"score": 0.39953909596222775,
"urls": ["url2"],
"ids": ["5743260055f979a31fa98971"]
}, {
"keyword": "name3",
"score": 0.4960953181766197,
"urls": ["url4"],
"ids": ["58c04cd5208b4945c3920cad"]
}, {
"keyword": "name4",
"score": 0.3337163443410707,
"urls": ["url5"],
"ids": ["573628c38e32eeb039377f7e"]
}];
var arr2 = [{
"keyword": "name",
"score": 0.8992112752974006,
"urls": ["url6"],
"ids": [""]
}, {
"keyword": "name1",
"score": 0.39953909596222775,
"urls": ["url7"],
"ids": [""]
}];
console.log(mergeObjects(arr1, arr2));
答案 5 :(得分:0)
ES5优化方法(没有不必要的迭代,只是" 低级"处理):
var arr1 = [{ keyword: "name", score: 0.8992112752974006, urls: ["url1"], ids: ["5748bf9ab58adb2f614da195"] }, { keyword: "name1", score: 0.39953909596222775, urls: ["url2"], ids: ["5743260055f979a31fa98971"] }, { keyword: "name3", score: 0.4960953181766197, urls: ["url4"], ids: ["58c04cd5208b4945c3920cad"] }, { keyword: "name4", score: 0.3337163443410707, urls: ["url5"], ids: ["573628c38e32eeb039377f7e"] }],
arr2 = [{ keyword: "name", score: 0.8992112752974006, urls: ["url6"], ids: [""] }, { keyword: "name1", score: 0.39953909596222775, urls: ["url7"], ids: [""] }],
len1 = arr1.length, c = 0, k = -1;
while (c < len1 && (l = arr2.length)) {
for (i=0; i<l; i++) {
if (arr1[c].keyword == arr2[i].keyword) {
arr1[c].urls.unshift(arr2[i].urls[0]);
k = i;
break;
}
}
if (k >=0) {
arr2.splice(k, 1);
k = -1;
}
c++;
}
console.log(arr1);
&#13;