JavaScript中数组去重的办法总结

 更新时间:2023年06月27日 10:42:52   作者:潘小七  
你是否在面试的过程中被考到过给你一个数组让你去掉重复项呢,下面小编就来总结一下对于数组去重这道简单的面试题时,我们可以回答的方法有什么吧

前言

你是否在面试的过程中被考到过给你一个数组让你去掉重复项呢?当时你的脑海里除了用Set实现之外,你还与面试官讲了什么去重的方法呢?你能否封装来一个可复用的数组去重api呢?依稀记得当时我被问到这个问题的时候,我也没回答出很多种解决办法。那下面我来总结一下对于数组去重这道简单的面试题时,我们可以回答的方法有什么吧。

数组去重

1. 不使用数组API方法

首先我来介绍一种不是用数组身上的API的去重解法,代码如下:

var array = ['1', 1, '1', '1', '2', 2]
function unique(array) {
    let res = []
    for(let i = 0; i < array.length; i++){
        for( var j = 0; j < res.length; j++){
            if(array[i]  === res[j]){
                break;
            }
        }
        if(j === res.length){
            res.push(array[i])
        }
    }
    return res 
}
console.log(unique(array)); // [ '1', 1, '2', 2 ]

既然不使用数组自带的API方法,那我们首先考虑的就是用双重for循环了,如上述代码:

  • 我们准备了一个空的结果数组
  • 我们对需要去重的数组进行循环
  • 在第一层数据中再套一层循环,根据下标判断结果数组内是否有重复项。

我们调用该方法,打印结构如上述代码的注解处,成功的实现了对数组的去重。

2. 使用 indexOf

既然有不使用数组API的,那就肯定有使用数组API的,下面看我使用indexOf完成数组的去重,代码如下:

var array = ['1', 1, '1', '1', '2', 2]
function unique(array) {
    let res = []
    for (let i = 0; i < array.length; i++) {
        if (res.indexOf(array[i]) === -1) { // 返回找到的第一个值得下标
            res.push(array[i])
        }
    }
    return res
}
console.log(unique(array))// [ '1', 1, '2', 2 ]

如上述代码, 我们巧妙了使用了indexOf查找结果数组中是否已经存在,如果不存在才向结果数组中添加,实现了数组去重。

在上述代码的基础上,我们还可以转变一下,将for循环内的语句改为

if (array.indexOf((array[i])) == array.lastIndexOf(array[i])) {
    i++
} else {
    array.splice(array.lastIndexOf(array[i]), 1)
}

不新增其他变量,直接通过indexOf和lastIndexOf判断该值是否在原数组内为唯一值,从而直接修改原数组,实现数组的去重。

3. 使用 sort

对于数组去重,我们除了通过下标找出是否有重复项之外,我们还可以先排序,然后在判断前后项是否相同来实现去重,代码如下:

var  array = [1, 3, 5, 4, 2, 1, 2, 4, 4, 4]
function unique(array) {
    let res = []
    let sortedArray = array.concat().sort() //concat() 返回新的数组
    let seen;
    for (let i = 0; i < sortedArray.length; i++) {
        if (!i || seen !== sortedArray[i]) {
            res.push(sortedArray[i])
        }
        seen = sortedArray[i]
    }
    return res
}
console.log(unique(array)); // [ 1, 2, 3, 4, 5 ]

如上述代码, 我们先获取一个排好序的新数组,再对新数组进行循环,判断保存前一个值的seen与当前值是否相同来实现数组去重。

温馨小提示: 由于数组的排序方法不能区分数组和字符串,所以想要使用此方法必须要保证数组的值的类型相同,不然会出bug

4. 使用 filter

既然都用到了sort排序了,那我直接抬出ES6数组新增的filter过滤器API也不过分吧,代码如下:

var array = ['1', 1, '1', '1', '2', 2]
function unique(array) {
    let res = array.filter((item, index, array) => {
        return array.indexOf(item) === index
    })
    return res
}
console.log(unique(array)); // [ '1', 1, '2', 2 ]

如上述代码,filter直接使用array.indexOf(item) === index作为过滤条件返回出一个新的数组,实现数组去重。

如上述代码,我们结合了 indexOf方法作为过滤条件,那我们也可以结合一下sort方法吧,直接使用一行代码就解决了数组的去重。代码如下:

function unique(array) {
    return array.concat().sort().filter((item, index, array) => !index || item !== array[item - 1])
}
console.log(unique(array)); // [ '1', 1, '2', 2 ]

5. 使用Set、Map、或者对象

除了上述的通过数组API和不使用数组API的方法外,我们还能想到的就是借助对象来实现数组的去重。使用Set数据结构是我们最容易想到的办法,使用Map与对象方法的相似,都是以数组的值作为key,再将所有的可以取出来组成一个数组。 我就不给小伙伴们演示代码了,感兴趣的小伙伴可以自己动手试试。

(对于对象的key只能为字符串这个问题,我们可以换个思路,将下标存为key,值存为value,判断不同key的值相不相同来实现数组去重。我们还可以在存key时加上其类型,然后进行一次转换。)

自己封装一个去重API

在介绍上述数组去重的方法后,我们再来总结一下,将其融合成一个有复用性,而且还可以适用不同情况的API方法。

我来介绍一下如下我封装的一个数组去重的API方法,

  • 该方法可接受三个参数,第一个参数为需要去重的数组,第二个参数为该数组是否为排好序的数组,第三个参数为一个回调函数
  • 该回调函数也有三个参数,分别为值,下标,需要去重数组。该回调函数的作用是方便用户对数组进行一些额外的处理(例如将大写转为小写)
  • 第二,三参数可不传递。
var array = [1, 2, '1', 'a', 'A', 2, 1]
var array2 = [1, 1, '1', 2, 2]
function uniq(array, isSorted, iteratee) {
    let  seen = []
    let res = []
    for(let i = 0; i < array.length; i++){
        let computed = iteratee ? iteratee(array[i], i,array) : array[i]
        if(isSorted) {
            if(!i || seen !== array[i]){
                res.push(array[i])
            }
            seen = array[i]
        }else if(iteratee) {
            if(seen.indexOf(computed) === -1){
                seen.push(computed)
                res.push(computed)
            }
        }
        else {
            if(res.indexOf(array[i]) === -1) {
                res.push(array[i])
            }
        }
    }
    return res
}
let result = uniq(array, false, function(item, index, arr){
    return typeof item == 'string' ? item.toLowerCase() : item
})
console.log(result); // [ 1, 2, '1', 'a' ]
console.log(uniq(array2, true)); // [ 1, 2 ]

总结

对于数组的去重,当我们能在面试中说到这个多方法的话,这道面试题也就过了,虽然这道面试不难,但如果我们想要想到这个多方法的话,还是需要许多知识储备的。

以上就是JavaScript中数组去重的办法总结的详细内容,更多关于JavaScript数组去重的资料请关注脚本之家其它相关文章!

相关文章

  • 在JS方法中返回多个值的方法汇总

    在JS方法中返回多个值的方法汇总

    本文给大家汇总了在javascript方法中返回多个值的方法,都是在个人项目中检验过的,这里推荐给大家,有需要的小伙伴可以参考下。
    2015-05-05
  • 从数组中随机取x条不重复数据的JS代码

    从数组中随机取x条不重复数据的JS代码

    这篇文章主要介绍了从数组中随机取x条不重复数据的JS代码,有需要的朋友可以参考一下
    2013-12-12
  • JavaScript Generator函数使用分析

    JavaScript Generator函数使用分析

    生成器Generator是JavaScript ES6引入的特性,它让我们可以分段执行一个函数。但是在谈论生成器(Generator)之前,我们要先了解迭代器Iterator
    2022-10-10
  • JS实现微信摇一摇原理解析

    JS实现微信摇一摇原理解析

    这篇文章主要为大家详细介绍了JS微信摇一摇的实现原理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • JS获得浏览器版本和操作系统版本的例子

    JS获得浏览器版本和操作系统版本的例子

    通过分析各类浏览器的userAgent信息,不难得出分辨各类浏览器及其版本的正则表达式。而且,对浏览器类型的判断和版本的判断完全可以合为一体地进行。
    2014-05-05
  • 微信小程序进行微信支付的步骤昂述

    微信小程序进行微信支付的步骤昂述

    最近开发微信小程序进入到支付阶段,一直以来从事App开发,所以支付流程还是熟记于心的。下面通过本文给大家讲述下微信小程序进行微信支付的步骤,需要的朋友可以参考下
    2016-12-12
  • JavaScript事件冒泡与事件捕获实例分析

    JavaScript事件冒泡与事件捕获实例分析

    这篇文章主要介绍了JavaScript事件冒泡与事件捕获,结合实例形式分析了事件冒泡、阻止冒泡以及事件捕获的相关原理、操作技巧与注意事项,需要的朋友可以参考下
    2018-08-08
  • JavaScript中数组去重的办法总结

    JavaScript中数组去重的办法总结

    你是否在面试的过程中被考到过给你一个数组让你去掉重复项呢,下面小编就来总结一下对于数组去重这道简单的面试题时,我们可以回答的方法有什么吧
    2023-06-06
  • antd项目实现彩蛋效果的详细代码

    antd项目实现彩蛋效果的详细代码

    这篇文章主要介绍了antd项目如何实现彩蛋效果,首先在components目录下创建Transform目录,包括index.css、index.js,index.js是主要的逻辑代码,下面对代码进行分析,需要的朋友可以参考下
    2022-09-09
  • js实现当复选框选择匿名登录时隐藏登录框效果

    js实现当复选框选择匿名登录时隐藏登录框效果

    这篇文章主要介绍了js实现当复选框选择匿名登录时隐藏登录框效果,实例分析了javascript动态操作页面元素样式的相关技巧,非常简单实用,需要的朋友可以参考下
    2015-08-08

最新评论