Js数组去重

135 阅读4分钟

ES6数组的扩展,Array.from(new Set())

更多ES6知识-ECMAScript 6 入门-阮一峰

Array.from()方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

Set本身是一个构造函数,用来生成 Set 数据结构。

注意: 向 Set 数据结构中加入值时认为NaN等于自身。

let list = ['我是一个数组', 2, 0, 2, 3, 1, 1, 3, 0, 5, 6, '我是一个数组', false, true, false, NaN, NaN];

let newList = Array.from(new Set(list))

console.log('newList', newList)
// newList [ '我是一个数组', 2, 0, 3, 1, 5, 6, false, true, NaN ]

ES6数组的扩展,实例方法includes + forEach

Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

array.forEach(callbackFn(currentValue, index, arr), thisValue)

注意: includes()方法认为NaN等于自身

let list = ['我是一个数组', 2, 0, 2, 3, 1, 1, 3, 0, 5, 6, '我是一个数组', false, true, false, NaN, NaN];

let newList = []

list.forEach(item => {
  if (!newList.includes(item)) newList.push(item)
})

console.log('newList', newList)
// newList [ '我是一个数组', 2, 0, 3, 1, 5, 6, false, true, NaN ]

ES6数组的扩展,new Map()

JavaScript的对象(Object),本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。

作为构造函数,Map也可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。

注意: 向 Map 数据结构中加入值时认为NaN等于自身。


let list = ['我是一个数组', 2, 0, 2, 3, 1, 1, 3, 0, 5, 6, '我是一个数组', false, true, false, NaN, NaN];

let newList = []

let map = new Map()

list.forEach(item => {
  if (!map.has(item)) {
    map.set(item, true)
    newList.push(item)
  }
})
// or
// list.forEach(item => {
//   if (!map.has(item)) {
//     map.set(item, true)
//   }
// })
// newList = Array.from( map.keys())

console.log('newList', newList)
// newList [ '我是一个数组', 2, 0, 3, 1, 5, 6, false, true, NaN ]

indexOf + forEach、filter、for等循环

indexOf() 方法可返回数组中某个指定的元素位置。

该方法将从头到尾地检索数组,看它是否含有对应的元素。开始检索的位置在数组 start 处或数组的开头(没有指定 start 参数时)。如果找到一个 item,则返回 item 的第一次出现的位置。开始位置的索引为 0。

如果在数组中没找到指定元素则返回 -1。

array.filter(function(currentValue,index,arr), thisValue)

返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。

注意: indexOf方法无法识别数组的 NaN 成员,[NaN].indexOf(NaN) -1,如果有NaN值可能会不同。

let list = ['我是一个数组', 2, 0, 2, 3, 1, 1, 3, 0, 5, 6, '我是一个数组', false, true, false, NaN, NaN];

let newList = []
list.forEach(item => {
  if (newList.indexOf(item) === -1) {
    newList.push(item)
  }
})
// newList [ '我是一个数组', 2, 0, 3, 1, 5, 6, false, true, NaN, NaN ]

// or
// let newList = list.filter((item, index) => {
//   return list.indexOf(item) === index
// })
// newList [ '我是一个数组', 2, 0, 3, 1, 5, 6, false, true ]

// or
// let newList = []
// for (let i = 0; i < list.length; i++) {
//   if (newList.indexOf(list[i]) === -1) {
//     newList.push(list[i])
//   }
// }
// newList [ '我是一个数组', 2, 0, 3, 1, 5, 6, false, true, NaN, NaN ]

console.log('newList', newList)

双层 for 循环

  • 双层for循环,外层循环元素,内层循环是比较值,如果有相同的值则跳过++i
let list = ['我是一个数组', 2, 0, 2, 3, 1, 1, 3, 0, 5, 6, '我是一个数组', false, true, false, NaN, NaN, 'NaN'];

let newList = []
let length = list.length

for (let i = 0; i < length; i++) {
  for (let j = i + 1; j < length; j++) {
    if (list[i] === list[j]) j = ++i
  }
  newList.push(list[i])
}

console.log('newList', newList)
// newList [ 2, 1, 3, 0, 5, 6, '我是一个数组', true, false, NaN, NaN, 'NaN' ]

单层 for 循环 + sort

sort() 方法用于对数组的元素进行排序。这种方法会改变原始数组。

array.sort(sortfunction)

注意: sort去重会对数组重新排序

let list = ['我是一个数组', 2, 0, 2, 3, 1, 1, 3, 0, 5, 6, '我是一个数组', false, true, false, NaN, NaN];

list.sort()
let newList = []

for (let i = 0; i < list.length; i++) {
  if (list[i] !== list[i + 1]) {
    newList.push(list[i])
  }
}

console.log('newList', newList)
// newList [ 0, 1, 2, 3, 5, 6, NaN, NaN, false, true, '我是一个数组' ]

双层 for 循环 + splice

splice() 方法用于添加或删除数组中的元素。这种方法会改变原始数组。

array.splice(index, howmany, item1,....., itemX)

如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组。 如果未删除任何元素,则返回空数组。

  • 取第一层for循环中的值,与第二层for循环中的每个值做对比
let list = ['我是一个数组', 2, 0, 2, 3, 1, 1, 3, 0, 5, 6, '我是一个数组', false, true, false, NaN, NaN, 'NaN'];

for (let i = 0; i < list.length; i++) {
  for (let j = i + 1; j < list.length; j++) {
    if (list[i] === list[j]) {
      list.splice(j, 1)
      j--
    }
  }
}

console.log('list', list)
// list [ '我是一个数组', 2, 0, 3, 1, 5, 6, false, true, NaN, NaN, 'NaN' ]

数组递归去重 + sort + splice

  • 先排序,再从后面开始比较

注意: sort去重会对数组重新排序

let list = ['我是一个数组', 2, 0, 2, 3, 1, 1, 3, 0, 5, 6, '我是一个数组', false, true, false, NaN, NaN, 'NaN'];

list.sort()

const length = list.length

function loop(index) {
  if (index >= 1) {
    if (list[index] === list[index - 1]) {
      list.splice(index, 1)
    }
    loop(index - 1)
  }
}

loop(length - 1)

console.log('list', list)
// list [ 0, 1, 2, 3, 5, 6, NaN, NaN, 'NaN', false, true, '我是一个数组' ]