超全的13种数组去重的方法

236 阅读6分钟

前言

数组去重,可以说是一个比较常见的面试题,今天,小编又刷到了一道关于数组去重的题目,今天那咱们就来盘点一下都有哪些方法可以实现数组去重。

方法一、双重for循环

这是一个最笨重的方法,双重循环。

var arr = [1,2,3,4,5,6,4,3,8,1]
    // 数组去重:
    // 方法1: 双重for 循环
    function newArrFn (arr) {
      // 创建一个新的空数组
      let newArr = []
      for(var i = 0;i<arr.length;i++){
        for(var j = i+1;j<arr.length;j++){
          if(arr[j]===arr[i]){
            break
          }
        }
        if(j==arr.length){
            newArr.push(arr[i])
        }
      };
     
      return newArr
    }
    console.log(newArrFn(arr));

方法二:for循环+indexof

var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
    // 数组去重:
    // 方法2: for + indexof
    function newArrFn (arr) {
      let newArr = []
      for(let i = 0;i<arr.length;i++){
        newArr.indexOf(arr[i]) === -1 ? newArr.push(arr[i]) : newArr
      };
      return newArr
    }
    console.log(newArrFn(arr));

在函数体内部,首先创建了一个空数组newArr,用于存放不重复的元素。然后,使用for循环遍历原始数组arr中的每个元素。对于每个元素arr[i],它会检查这个元素是否已经在newArr中存在(通过indexOf方法)。如果newArr.indexOf(arr[i])返回-1,这意味着元素arr[i]newArr中不存在,因此使用三元运算符将其添加到newArr中。否则,如果元素已经存在,什么也不做。

方法三:sort排序

var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
    // 数组去重:
    // 方法3: for + sort
    function newArrFn (arr) {
      arr = arr.sort()
      let newArr = []
      for(let i = 0;i<arr.length;i++){
        arr[i] === arr[i-1] ? newArr : newArr.push(arr[i])
      };
      return newArr
    }
    console.log(newArrFn(arr));

在这里咱们创建一个新的空数组newArr用于存储不重复的元素。然后使用for循环遍历排序后的数组arr。在每次迭代中,它检查当前元素arr[i]是否与前一个元素arr[i-1]相等。如果它们相等(意味着arr[i]是一个重复项),则不执行任何操作。如果它们不相等,则将当前元素arr[i]推送到newArr中。

方法四:双指针法

var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
var newArrFn = function(nums) {
  const n=nums.length;
  nums=nums.sort((a,b)=>a-b)
  if(n==0){
      return 0
  }
  let fast=1,slow=1;
  let newArr=[]
  newArr.push(nums[fast-1])
  while(fast<n){
      if(nums[fast]!==nums[fast-1]){
          newArr.push(nums[fast])
          nums[slow]=nums[fast]
          slow++
      }
      fast++
  }
  
  return newArr
};
console.log(newArrFn(arr));

首先对得到的数组进行一个升序排序,接着初始化两个指针fastslow,都设置为1(即数组的第二个元素的索引)。同时,创建一个空数组newArr,用于存储去重后的元素。这里将nums的第一个元素推入newArr中,因为fastslow都从1开始,使用while循环遍历数组。在每次迭代中,if语句检查fast指针所指向的元素是否与前一个元素不同。如果是不同的,newArr将添加该元素,并将该元素复制到numsslow指针所指向的位置,然后slow指针向前移动一位。无论元素是否相同,fast指针都会向前移动一位。最终返回一个新数组newArr即为去重后的数组。

方法五:set

ES6中新增了数据类型Set,Set的一个最大的特点就是数据不重复Set函数可以接受一个数组(或类数组对象)作为参数来初始化,利用该特性也能做到给数组去重。

var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
    // 数组去重:
    // 方法5: set
    function newArrFn (arr) {
      // .new Set方法,返回是一个类数组,需要结合 ...运算符,转成真实数组
      return ([...new Set(arr)])
    }
    console.log(newArrFn(arr));

方法六:set + Array.from

利用 set数据不重复的特点,结合 Array.from

var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
    // 数组去重:
    // 方法6: set + Array.from
    function newArrFn (arr) {
      // .new Set方法,返回是一个类数组,需要结合 Array.from ,转成真实数组
      return (Array.from(new Set(arr)) )
    }
    console.log(newArrFn(arr));

方法七:filter + indexOf

indexOf,可以检测某一个元素在数组中出现的位置,找到返回该元素的下标,没找到返回 -1

var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
    // 数组去重:
    // 方法7 :filter + findIndex
    function newArrFn (arr) {
      // 利用indexOf检测元素在数组中第一次出现的位置是否和元素现在的位置相等,
      // 如果相等,说明数组中没有重复的
      return Array.prototype.filter.call(arr, function (item, index) { 
        return arr.indexOf(item) === index
       })
    }
    console.log(newArrFn(arr));

方法八:includes

利用 includes 检查新数组是否包含原数组的每一项。 如果不包含,就push进去

var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
    // 数组去重:
    // 方法8 :for + includes
    function newArrFn (arr) {
      // 利用includes 检查新数组是否包含原数组的每一项
      // 如果不包含,就push进去
      let newArr = []
      for(let i = 0;i<arr.length;i++){
        newArr.includes(arr[i]) ? newArr:  newArr.push(arr[i]) 
      };
      return newArr
    }
    console.log(newArrFn(arr));

方法九:for + object

利用对象属性名不能重复这一特点。如果对象中不存在,就可以给 push 进去

var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
    // 数组去重:
    // 方法9 :for + obj
    function newArrFn (arr) {
      // 利用对象属性名不能重复这一特点
      // 如果对象中不存在,就可以给 push 进去
      let newArr = []
      let obj = {}
      for(let i = 0;i<arr.length;i++){
        if (!obj[arr[i]]) {
          newArr.push(arr[i])
          obj[arr[i]] = 1
        } else {
          obj[arr[i]] ++
        }
      };
      return newArr
    }
    console.log(newArrFn(arr));

方法十:for+splice

利用 splice 进行切割

var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
    // 数组去重:
    // 方法10 :for + splice
    // 利用 splice 进行切割。
    function newArrFn (arr) {
      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);
            j--
          }
        };
        }
        return arr
    }
    console.log(newArrFn(arr));

方法十一:filter + indexOf

利用 filter 过滤 配合 indexOf 查找元素

var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
    // 数组去重:
    // 方法11 :filter + indexOf
    // filter 过滤 配合 indexOf 查找元素
    function newArrFn (arr) {
      return arr.filter((item, index) => {
        return arr.indexOf(item) === index
      })
    }
    console.log(newArrFn(arr));

方法十二:Map

利用数据结构存值的特点

var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
    // 数组去重:
    // 方法12 :Map
    function newArrFn (arr) {
      let newArr = []
      let map = new Map()
      for(let i = 0;i<arr.length;i++){
        // 如果 map里面不包含,就设置进去
        if (!map.has(arr[i])) {
          map.set(arr[i], true)
          newArr.push(arr[i])
        }
      };
      return newArr
    }
    console.log(newArrFn(arr));

方法十三:reduce

var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
    // 数组去重:
    // 方法13 :reduce
    function newArrFn (arr) {
      let newArr = []
      return  arr.reduce((prev, next,index, arr) => {
        // 如果包含,就返回原数据,不包含,就把新数据追加进去 
        return newArr.includes(next) ? newArr :  newArr.push(next)
      }, 0)
    }
    console.log(newArrFn(arr));

reduce函数是用来对数组的每一个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。在这里,reduce函数的调用形式如下:

  • (prev, next, index, arr)prev是上一次调用callback返回的值,或者是提供的初始值(在这里是0)。next是当前元素,index是当前元素的索引,arr是原数组。
  • return newArr.includes(next) ? newArr : newArr.push(next):这一行的意图是在newArr不包含next时将next添加到newArr中。但是,这里的问题在于reduce的返回值被忽略了,它不会更新newArr。此外,newArr.push(next)直接返回的是newArr的长度,而不是newArr本身。

好啦,今天的分享就到这里了,不知道屏幕前的你是否还有其他关于数组去重的方法,欢迎评论区留言讨论。可以点个免费的赞赞嘛,感谢感谢!