数组去重

方法说明
Set对象不去重,NaN 去重
双层 for 循环对象和 NaN 都不去重
filter + indexOf对象不去重,NaN 会被忽略
filter + Object 键值对全部去重
var arr = [
  1, 
  1,
  '1', 
  '1',
  null, 
  null,
  undefined, 
  undefined,
  new String('1'), 
  new String('1'),
  /a/, 
  /a/,
  NaN, 
  NaN,
]
// 法一:set
[...new Set(arr)]
Array.from(new Set(arr))

// 法二:双层 for 循环
for (let i = 0; i < arr.length; i++) {
  for (let j = i + 1; j < arr.length; j++) {
    if (arr[i] == arr[j]) {
      arr.splice(j, 1)

      // 去重后会改变数组长度,所以要将数组长度 arr.length 和下标 j 减一
      arr.length--
      j--
    }
  }
}

// 法三:filter + indexOf
// 利用 indexOf 返回指定值第一次出现的索引的索引,若后面发现 indexOf 返回值和元素自身索引对不上,就去重
arr.filter((item, index, array) => array.indexOf(item) === index)

// 法四:filter + Object 键值对
// 利用一个空对象,将数组值依次存入对象,若存的时候发现对象中已经有该值了,就去重
// 对象属性都是字符串,通过 typeof item + item,来将数字拼成字符串,防止误差
// 赋值语句返回值是等号右边的值
const obj = {}
array.filter((item) => obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)

// 其他方法暂不整理,可参考
// http://www.inode.club/interview/unique.html
// https://github.com/mqyqingfeng/Blog/issues/27
Last Updated:
Contributors: Vsnoy