实现数组元素追加逻辑:已存在则排除,不存在则添加
数组去重合并实现方案
这是个很常见的数组元素合并去重需求,我给你几个实用的实现方案,适配不同场景:
方案一:返回新数组(推荐,不修改原数组)
这种方式不会改动原有的arr1和arr2,返回一个全新的合并后数组,适合需要保留原数据的场景:
// 先提取arr1中所有元素的id,存入Set实现O(1)快速查找 const existingIds = new Set(arr1.map(item => item.id)); // 过滤arr2中id未在arr1出现过的元素,再和arr1合并 const mergedArray = [...arr1, ...arr2.filter(item => !existingIds.has(item.id))];
为什么用Set? 因为Set的has()方法查找效率是O(1),比用arr1.some(item => item.id === targetId)的O(n)高效得多,当数组元素数量较多时,性能差异会很明显。
方案二:直接修改原数组
如果你的业务场景允许直接修改arr1,可以用这种更节省内存的方式:
const existingIds = new Set(arr1.map(item => item.id)); arr2.forEach(item => { if (!existingIds.has(item.id)) { arr1.push(item); existingIds.add(item.id); // 顺便更新Set,避免arr2内部存在重复id时重复添加 } }); // 此时arr1已经是合并去重后的数组
这种方法会直接把符合条件的元素追加到原arr1末尾,同时处理了arr2自身可能存在重复id的情况。
方案三:基于Map的扩展性方案
如果未来你的需求可能扩展为「存在则更新,不存在则添加」,用Map会更灵活:
// 用arr1的元素构建以id为键的Map const itemMap = new Map(arr1.map(item => [item.id, item])); // 遍历arr2,仅添加id不存在的元素 arr2.forEach(item => { if (!itemMap.has(item.id)) { itemMap.set(item.id, item); } // 若以后要改成"存在则更新",只需把上面的判断改成: // itemMap.set(item.id, item); }); // 将Map的值转换为数组 const mergedArray = Array.from(itemMap.values());
这种方式的优势在于后续需求变更时,代码改动极小,同时保持了高效的查找性能。
注意事项
- 以上方案都依赖
id作为唯一标识,请确保id是数字、字符串这类可以被Set/Map正确识别的基本类型;如果id是引用类型,需要自定义比较逻辑。 - 如果你的运行环境不支持ES6+语法(比如旧版IE),可以把Set换成对象来存储id,比如
const existingIds = {}; arr1.forEach(item => existingIds[item.id] = true);,查找时用!existingIds[item.id]即可。
内容的提问来源于stack exchange,提问作者Denis Stephanov
相关产品推荐
相关产品推荐

