采用 高效哈希映射法 处理合并逻辑
/**
* 根据相同id合并两个对象数组
* @param {Array} arr1 - 第一个对象数组
* @param {Array} arr2 - 第二个对象数组
* @param {Function} [mergeStrategy] - 自定义合并策略函数 (可选)
* @returns {Array} 合并后的新数组
*/
function mergeArraysById(arr1, arr2, mergeStrategy) {
// 创建哈希映射,用于快速查找和合并
const map = new Map();
// 定义默认合并策略:后者覆盖前者
const defaultStrategy = (existing, current) => ({ ...existing, ...current });
// 使用传入的合并策略或默认策略
const merge = mergeStrategy || defaultStrategy;
// 处理第一个数组
arr1.forEach(item => {
if (item.id !== undefined) {
map.set(item.id, { ...item });
}
});
// 处理第二个数组
arr2.forEach(item => {
if (item.id === undefined) return;
const existing = map.get(item.id);
if (existing) {
map.set(item.id, merge(existing, item));
} else {
map.set(item.id, { ...item });
}
});
// 返回合并后的数组
return Array.from(map.values());
}
// 示例用法
const arr1 = [
{ id: 1, name: 'Alice', tags: ['a'] },
{ id: 2, name: 'Bob' }
];
const arr2 = [
{ id: 1, age: 25, tags: ['b'] },
{ id: 3, name: 'Charlie' }
];
// 默认合并(后者覆盖前者)
const merged1 = mergeArraysById(arr1, arr2);
console.log('默认合并策略:', merged1);
/* 输出:
[
{ id:1, name:'Alice', age:25, tags:['b'] },
{ id:2, name:'Bob' },
{ id:3, name:'Charlie' }
]
*/
// 自定义合并策略:数组类型属性合并
const arrayMergeStrategy = (existing, current) => ({
...existing,
...current,
tags: [...(existing.tags || []), ...(current.tags || [])]
});
const merged2 = mergeArraysById(arr1, arr2, arrayMergeStrategy);
console.log('数组属性合并:', merged2);
/* 输出:
[
{ id:1, name:'Alice', age:25, tags:['a','b'] },
{ id:2, name:'Bob' },
{ id:3, name:'Charlie' }
]
*/
优化性能(哈希映射法)
let arr = [
{ id: 1, name: '张三' },
{ id: 2, name: '李四' },
];
let arr1 = [
{ id: 1, age: '23' },
{ id: 3, age: '45' },
];
const map = new Map(arr1.map(item => [item.id, { ...item }]));
arr.forEach(item => {
const existing = map.get(item.id);
map.set(item.id, existing ? { ...existing, ...item } : { ...item });
});
const list = Array.from(map.values());
利用reduce&&find
let arr = [
{ id: 1, name: '张三' },
{ id: 2, name: '李四' },
];
let arr1 = [
{ id: 1, age: '23' },
{ id: 3, age: '45' },
];
//方法1
const merged = [...arr1, ...arr].reduce((acc, cur) => {
const existing = acc.find((item) => item.id === cur.id);
return existing ? acc.map((item) => (item.id === cur.id ? { ...item, ...cur } : item)) : [...acc, cur];
}, []);
console.log(merged);
//方法2
const list = arr.reduce(
(pre, cur) => {
const copy = { ...cur }; // 创建副本避免引用共享
const target = pre.find((ee) => ee.id === copy.id);
if (target) {
Object.assign(target, copy);
} else {
pre.push(copy);
}
return pre;
},
[...arr1]
); // 使用展开运算符创建arr1的副本
console.log(list);