javaScript实现数组去重

121 阅读2分钟

js常见的几种数组去重方法

1.includes

let res = []
for (let i = 0; i < arr.length; i++) {
// 每一循环之后includes判断新数组中是否已经push进了数组,没有的话push
  if (!res.includes(arr[i])) {
    res.push(arr[i])
  }
}

2.indexOf

//和includes类似
let res = []
for (let i = 0; i < arr.length; i++) {
  // 判断元数组的元素在新数组中首次出现的位置,如果为-1标识没有出现过进入push
  if (res.indexOf(arr[i])===-1) {
    res.push(arr[i])
  }
 }

3.findIndex

let res = []
// findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回 -1。
// 如果第一次出现的索引等于下标就推进新数组
for (let i = 0; i < arr.length; i++) {
 // 如果第一次出现的索引等于下标就推进新数组 
 if(i===arr.findIndex((el)=>{return el===arr[i]})){
   console.log(arr[i])//3,2,7,5
   res.push(arr[i])
 }
}

4.Set

// 语法new Set(iterable):传递一个可迭代对象(这里传入数组),它的所有元素将不重复地被添加到新的 Set 中. 
console.log(new Set([1,2,2,3]))// Set(3) {1, 2, 3}
console.log(...(new Set([1,2,2,3])))// 1 2 3
console.log([...(new Set([1,2,2,3]))])// (3) [1, 2, 3]
// 按以上三步
let arr = [1,2,2,3]
const newArr = [...(new Set(arr))]// [1,2,3]

5.Set配合from

// Array.from() //方法对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
let arr = [1,2,2,3,4,4]
console.log(Array.from(new Set(arr)))//(4) [1, 2, 3, 4]

6.遍历相邻元素

// 相邻元素:先sort从小到大排序,之后遍历排好的相邻元素相同的时候停止本次push赋值,直接到下一次循环
arr.sort((a,b)=>{return a-b})
for (let i = 0; i < arr.length; i++) {
// 数组相邻的元素不相同,push,arr[i]是undefined一定(不相等)进来 
  if(arr[i]!==arr[i+1]){
   newArr.push(arr[i])
  }
}

7.数组元素作为对象的属性

//创建一个空对象,对数组的每一个元素判断,如果对象身上没有属性(这个属性名是正在遍历的元素的值),将这个属性名设置为元素的值,属性值设置为true,如果对象身上有这个属性(这个属性名是正在遍历的元素的值),不操作,直接下轮循环
// for循环实现
let obj = {}
let newArr = []
for (let i = 0; i < arr.length; i++) {
  // 如果没有这个属性,将这个属性的值设置为true(1也行确保下次判断进不去)
  if(!obj[arr[i]]){
    obj[arr[i]] = true
    newArr.push(arr[i])
  }
}

// reduce实现
// reduce((a,b)=>{},e),abe形参分别表示:上一次处理的返回值,数组元素, e:初始值
let obj = {}
// 每一次循环将数组的值设置对象的属性,没有这个属性就添加属性(属性值为true(为1也行)))同时push进新数组, 
return arr.reduce((acc,item) => {
  // 如果对象的键名为数组元素的键值为空,将这个键值设置为true同时push元素到新数组 
  obj[item] ? '': (obj[item] = true && acc.push(item))
  return acc
}, [])

8.双重for循环实现

let res = []
for (let i = 0; i < arr.length; i++) {
  //flag标识是否添加数组,true标识要push添加,false标识不添加 
  let flag = true
  // 遍历新数组,发现有写元数组一样的数据的时候将标识添加的标识符flag设置为false,并直接结束内层循环 
  for (let j = 0; j < res.length; j++) {
    if (arr[i] === res[j]) {
      flag = false
      break
    }
  }
  // 如果源数原组下标为i的数组的标识为true标识没有重复的,将这个数组push进新数组
  if (flag) {
    res.push(arr[i])
  }
}