根据相同 id 合并两个对象数组

 采用 高效哈希映射法 处理合并逻辑

/**
 * 根据相同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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值