developer-plus / interview

https://interview.developer-plus.org
MIT License
9 stars 1 forks source link

手写题:如何实现数组去重? #2

Open chenfan0 opened 2 years ago

chenfan0 commented 2 years ago

注意:下面的arr参数为存放基本数据类型的数组。

方式一:使用数据结构Set帮助我们进行去重。

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

方式二:通过循环+includes进行去重。

function unique(arr) {
  const result = []

  for (const item of arr) {
    // 判断result是否已经有该元素了,如果没有再进行添加。
    if (!result.includes(item)) {
      result.push(item)
    }
  }
  return result
}

方式三:通过filter + indexOf进行去重。

function unique2(arr) {
  // 如果当前元素的下标和indexOf的下标不相同,则证明数组前面已经有相同的元素了,所以将当前元素排除掉。
  return arr.filter((item, index) => arr.indexOf(item) === index)
}

其实还会有一些其他的方法进行去重,但是本质上就是通过循环加上判断当前的值是否已经添加过。

luckept commented 2 years ago

一种别致的去重方式:核心思想为利用逗号运算符

/**
 * 数组去重
 * @param {*} arr 待去重数组
 * @param {*} unique_key 依据数据结构中的哪个标识去去重
 * @returns 
 */
function unique(arr, unique_key) {
  return Object.values(arr.reduce((acc, cur) => (acc[cur[unique_key]] = cur, acc) , {}))
}

配套测试用例如下

const user = [
  {
    uid: 1, uname: '用户1',
  },
  {
    uid: 2, uname: '用户2',
  },
  {
    uid: 3, uname: '用户3',
  },
  {
    uid: 4, uname: '用户4',
  },
  {
    uid: 1, uname: '用户1',
  },
]

console.log(unique(user, 'uid'))

如何理解这里提到的逗号运算符?

代码中此处 (acc, cur) => (acc[cur[unique_key]] = cur, acc) 利用逗号的特性,先对 acc 做一系列逻辑处理,然后返回 acc