在js开发中,合并多个对象数组是常见需求,merge是处理这类场景的核心思路,不同合并规则对应不同的实现方式,下面介绍几种常用的实现方案。

基础合并:保留所有元素
如果只是需要把多个对象数组的所有元素合并到一个新数组中,不需要去重,可以使用数组的concat方法,也可以模拟merge的思路手动实现。
concat方法是最简单的实现方式,它会返回一个新的数组,不会修改原数组:
// 定义多个对象数组
const arr1 = [{id: 1, name: '张三'}, {id: 2, name: '李四'}];
const arr2 = [{id: 3, name: '王五'}, {id: 4, name: '赵六'}];
const arr3 = [{id: 5, name: '钱七'}];
// 使用concat合并多个数组
const mergedArr = arr1.concat(arr2, arr3);
console.log(mergedArr);
// 输出:[{id:1,name:'张三'},{id:2,name:'李四'},{id:3,name:'王五'},{id:4,name:'赵六'},{id:5,name:'钱七'}]
如果需要手动实现类似merge的合并逻辑,也可以通过遍历数组push元素的方式:
function mergeArrays(...arrays) {
const result = [];
// 遍历所有传入的数组
arrays.forEach(arr => {
if (Array.isArray(arr)) {
result.push(...arr);
}
});
return result;
}
const arr1 = [{id: 1, name: '张三'}, {id: 2, name: '李四'}];
const arr2 = [{id: 3, name: '王五'}];
const merged = mergeArrays(arr1, arr2);
console.log(merged);
去重合并:按指定属性去重
实际开发中更常见的是需要合并多个对象数组,并且按照对象的某个唯一属性(比如id)去重,重复的元素只保留一个。这种场景可以结合对象哈希和merge的思路实现。
function mergeAndUniqueByKey(...arrays) {
const map = new Map();
// 遍历所有数组的元素
arrays.forEach(arr => {
if (Array.isArray(arr)) {
arr.forEach(item => {
// 以id作为唯一标识,重复id的元素会被后面的覆盖
if (item.id !== undefined) {
map.set(item.id, item);
}
});
}
});
// 把map的值转成数组返回
return Array.from(map.values());
}
const arr1 = [{id: 1, name: '张三'}, {id: 2, name: '李四'}];
const arr2 = [{id: 2, name: '李四海'}, {id: 3, name: '王五'}];
const arr3 = [{id: 1, name: '张三三'}, {id: 4, name: '赵六'}];
const mergedUnique = mergeAndUniqueByKey(arr1, arr2, arr3);
console.log(mergedUnique);
// 输出:[{id:1,name:'张三三'},{id:2,name:'李四海'},{id:3,name:'王五'},{id:4,name:'赵六'}]
使用第三方库的merge方法
如果项目中已经引入了lodash等工具库,也可以直接使用库提供的merge相关方法处理对象数组合并,lodash的merge方法可以深度合并对象,但处理数组时默认是替换而不是合并,所以需要结合其他方法使用。
如果需要合并多个对象数组并去重,可以使用lodash的unionBy方法,它支持按指定属性去重合并:
// 假设已经引入lodash,这里模拟lodash的unionBy逻辑
// 实际使用时直接调用_.unionBy即可
function unionBy(...arrays, key) {
const map = new Map();
arrays.forEach(arr => {
if (Array.isArray(arr)) {
arr.forEach(item => {
const keyValue = item[key];
if (keyValue !== undefined && !map.has(keyValue)) {
map.set(keyValue, item);
}
});
}
});
return Array.from(map.values());
}
const arr1 = [{id: 1, name: '张三'}, {id: 2, name: '李四'}];
const arr2 = [{id: 2, name: '李四海'}, {id: 3, name: '王五'}];
const result = unionBy(arr1, arr2, 'id');
console.log(result);
注意事项
- 合并对象数组时,如果对象有嵌套属性,需要根据实际需求决定是否需要深度合并嵌套属性,上述示例都是浅合并,嵌套对象会被直接替换。
- 使用Map去重时,要注意key的类型,如果id是数字和字符串混合,需要统一key的类型,避免去重失效。
- 手动实现merge逻辑时,要先判断传入的参数是否为数组,避免报错。