Skip to content

数组去重

数组去重的核心目标是:去掉重复项,同时尽量保留原有顺序。

最常见的写法:Set

js
function unique(arr) {
  return [...new Set(arr)]
}

console.log(unique([1, 2, 2, 3, 3])) // [1, 2, 3]

这是日常开发里最常用的方案,优点是:

  • 写法最短
  • 可读性最好
  • 默认保留首次出现顺序

另一种常见写法:filter + indexOf

js
function unique(arr) {
  return arr.filter((item, index) => arr.indexOf(item) === index)
}

这个方案更适合理解“为什么能去重”,但现在一般不如 Set 直接。

两种方案的差异

可以先这样理解:

  • Set:利用集合天然不重复的特性
  • filter + indexOf:保留第一次出现的位置

一个容易忽略的边界

如果数组元素是对象:

js
const list = [{ id: 1 }, { id: 1 }]
console.log([...new Set(list)])

这并不会按对象内容去重,因为对象比较的是引用,不是结构。

按对象字段去重

如果希望按某个字段去重,通常要自己建立映射:

js
function uniqueBy(arr, key) {
  const seen = new Set()

  return arr.filter((item) => {
    if (seen.has(item[key])) {
      return false
    }

    seen.add(item[key])
    return true
  })
}

const users = [
  { id: 1, name: 'A' },
  { id: 1, name: 'B' },
  { id: 2, name: 'C' },
]

console.log(uniqueBy(users, 'id'))

使用建议

  • 普通值数组去重,优先用 Set
  • 需要按对象字段去重时,使用 SetMap 记录键。
  • 面试题里如果被要求不用 Set,再写 filter + indexOf 或哈希表方案。

基于 MIT 许可发布