2022-08-13 09:38:00
在JavaScript中合并两个数组并去除重复项,可根据数组元素类型选择不同方法,以下是具体方案:
原始类型数组(数字、字符串、布尔值、null、undefined、NaN)使用 Set 结合展开运算符 是最简洁高效的方式,Set 会自动处理唯一性,包括将 NaN 视为单一值。
function mergeAndDeduplicateArrays(arr1, arr2) { return [...new Set([...arr1, ...arr2])];}// 示例const arrayA = [1, 2, 3, 4, 'a', 'b', null, undefined];const arrayB = [3, 4, 5, 6, 'b', 'c', null, undefined, NaN];const result = mergeAndDeduplicateArrays(arrayA, arrayB);console.log(result); // 输出:[1, 2, 3, 4, 'a', 'b', null, undefined, 5, 6, 'c', NaN]
优势:
Set 基于引用判断对象相等,即使两个对象属性相同,只要引用不同也会被视为不同。此时需采用以下方法:
1. 基于唯一 ID 的 Map 去重法(推荐)遍历合并后的数组,以对象唯一标识符(如 id)为键存入 Map,后出现的同 ID 对象会覆盖前者,最后转回数组。
function mergeAndDeduplicateObjectsById(arr1, arr2) { const combined = [...arr1, ...arr2]; const uniqueMap = new Map(); for (const item of combined) { if (item && item.id !== undefined) { uniqueMap.set(item.id, item); } } return Array.from(uniqueMap.values());}// 示例const arrObj1 = [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}];const arrObj2 = [{id: 2, name: 'Robert'}, {id: 3, name: 'Charlie'}];const resultObj = mergeAndDeduplicateObjectsById(arrObj1, arrObj2);console.log(resultObj);// 输出:[{id: 1, name: 'Alice'}, {id: 2, name: 'Robert'}, {id: 3, name: 'Charlie'}]优势:
将对象序列化为字符串后用 Set 去重,但受限于属性顺序、不可序列化值(如函数、undefined)及循环引用问题。
function mergeAndDeduplicateObjectsByStringify(arr1, arr2) { const combined = [...arr1, ...arr2]; const uniqueStrings = new Set(); const uniqueObjects = []; for (const item of combined) { try { const itemString = JSON.stringify(item); if (!uniqueStrings.has(itemString)) { uniqueStrings.add(itemString); uniqueObjects.push(item); } } catch (e) { console.warn("无法序列化对象,跳过:", item, e); } } return uniqueObjects;}// 示例const arrObj3 = [{a:1, b:2}, {b:2, a:1}, {c:3}];const arrObj4 = [{a:1, b:2}, {d:4}];const resultStr = mergeAndDeduplicateObjectsByStringify(arrObj3, arrObj4);console.log(resultStr);// 输出:[{a:1, b:2}, {c:3}, {d:4}](注意属性顺序敏感问题)局限性:
原始类型优先用 Set,对象类型优先基于唯一 ID 使用 Map。
避免循环嵌套 indexOf 或 includes,其时间复杂度为 O(n²)。
若数据来源已保证唯一性,无需去重。
大数据量时考虑增量更新,仅处理新增或变化部分。
在后端或数据源层面保证数据唯一性。
为对象定义明确且易于访问的唯一 ID。
使用浏览器开发者工具(如 Chrome DevTools 的 Performance 面板)定位耗时操作。
