我有两个对象数组:
var arr1 = [{
"id": "id_1",
"name": "Skoda"
}, {
"id": "id_2",
"name": "BMW"
}];
var arr2 = [{
"id": "id_1",
"name": "Skoda - Auto"
}, {
"id": "id_3",
"name": "BMW - Auto"
},{
"id": "id_4",
"name": "Merc - Auto"
}]
输出
var arr1 = [{
"id": "id_3",
"name": "BMW - Auto"
},{
"id": "id_4",
"name": "Merc - Auto"
},{
"id": "id_1",
"name": "Skoda"
}, {
"id": "id_2",
"name": "BMW"
}];
我想合并两个数组 arr1 和 arr2,基本上,只有当 Id 不存在于 arr1 中时,我才想将对象从 arr2 取消移动到 arr1,因此我们不会将
id_1
添加到 arr1。我不知道我们怎样才能实现它
我尝试了以下方法,但它不断添加重复的项目,如何避免 id 重复
arr1.unshift.apply(arr1, arr2)
您可以将所有数据集缩减到
Map
。
对于数据集中的每个项目,通过将其分配到最后来确定第一次出现的优先级。
注意:
accInner
从技术上讲是 accOuter
,但为了每个 reduce
操作的累加器参数,它们被区分为单独的变量。它们都是对 Map()
初始化器的引用。
此外,
k
是id
的item[key]
字段(键)的值。我使用 IIFE(立即调用函数执行)来避免创建块作用域并将其分配为变量。
// First occurrence of `name` and `a` stays
const arr1 = [
{ "id": "id_1", "name": "Skoda", "a": 1 },
{ "id": "id_2", "name": "BMW" }
];
// Do not override `name` or `a`, but add `b`
const arr2 = [
{ "id": "id_1", "name": "Skoda - Auto", "a": 0, "b": 2 },
{ "id": "id_3", "name": "BMW - Auto" },
{ "id": "id_4", "name": "Merc - Auto" }
];
const mergeByKey = (key, ...dataSets) =>
[...dataSets
.reduce((accOuter, dataSet) =>
dataSet.reduce((accInner, item) =>
((k) =>
accInner.set(k, Object.assign({}, item, accInner.get(k)))) // priority
(item[key]), accOuter), new Map)
.values()]
const arr3 = mergeByKey('id', arr1, arr2); // Priority is left-to-right
console.log(arr3);
.as-console-wrapper { top: 0; max-height: 100% !important; }