两个接口分别返回已选标签,合并后同一个标签出现两次。用 concat 拼完没处理,列表渲染出来就是重复项,点删除还会连带删两条。
基本类型一行搞定
const a = ['前端', '后端', '运维']; const b = ['运维', '设计']; const c = [...new Set([...a, ...b])];结果按插入顺序保留,先出现的排前面,去重后顺序稳定。数字、字符串、布尔值都适用。注意字符串 1 和数字 1 算两个不同的值,混合类型的接口要统一一次。
对象数组不能直接塞 Set
Set 比较的是引用,两个内容相同的对象字面量也算不同元素,直接去重等于没去。实际项目里一般按 id 处理,用 Map 记一遍最直观。
const list = [...arr1, ...arr2]; const map = new Map(); list.forEach(item => { if (!map.has(item.id)) map.set(item.id, item); }); const result = [...map.values()];想让后面那条覆盖前面那条,去掉判断直接 set 就行,键的位置不会变,顺序仍然稳定。
几个实际会遇到的问题
- 数组特别大时,Set 比 filter 加 indexOf 快一个量级,后者是平方复杂度。
- 要去掉空值,在展开前先 filter(Boolean),别去完重再补。
- 要忽略大小写,先把值转小写当键,否则 Apple 和 apple 会各留一条。
- 合并后要排序,去重完再 sort,位置才可控。