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 中,进程和线程的概念并不是直接暴露给开发者的,而是通过浏览器或 Node.js 等执行环境来实现的,文中介绍的非常详细,感兴趣的同学可以阅读一下
    2023-04-04
  • 《javascript设计模式》学习笔记五:Javascript面向对象程序设计工厂模式实例分析

    《javascript设计模式》学习笔记五:Javascript面向对象程序设计工厂模式实例分析

    这篇文章主要介绍了Javascript面向对象程序设计工厂模式,结合实例形式分析了《javascript设计模式》中Javascript面向对象工厂模式相关概念、原理、用法及操作注意事项,需要的朋友可以参考下
    2020-04-04
  • js中几种去掉字串左右空格的方法

    js中几种去掉字串左右空格的方法

    js中几种去掉字串左右空格的方法...
    2006-12-12
  • reveal.js PPT制作框架使用教程

    reveal.js PPT制作框架使用教程

    reveal.js是一款开源的HTML演示框架,由Hakim El Hattab开发,遵循MIT许可证,它支持嵌套幻灯片、Markdown、自动动画、PDF导出等多种功能,本文就来介绍一下如何使用,感兴趣的可以了解一下
    2024-09-09
  • uni-app实现微信小程序长按拍视频功能

    uni-app实现微信小程序长按拍视频功能

    这篇文章主要为大家详细介绍了uni-app实现微信小程序长按拍视频功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • webpack -v报错解决方案

    webpack -v报错解决方案

    这篇文章主要介绍了webpack -v报错解决方案,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • JS格式化数字保留两位小数点示例代码

    JS格式化数字保留两位小数点示例代码

    式化数字保留两位小数点实现的方法有很多,在接下来的文章中将为大家详细介绍下如何使用js来实现
    2013-10-10
  • ymPrompt的doHandler方法来实现获取子窗口返回值的方法

    ymPrompt的doHandler方法来实现获取子窗口返回值的方法

    今天在写页面时用到了ymPrompt的win方法来弹出一个窗口。由于要用到获取子窗口返回来的值判断是否刷新父窗口,在ymPrompt的组件Demo中一直没有找到合适的方法实现
    2010-06-06
  • ECharts两种动画效果完整代码

    ECharts两种动画效果完整代码

    这篇文章主要给大家介绍了关于ECharts两种动画效果的相关资料,在做项目时当我们用到echarts图表时,大部分产品经理都会要求我们给图表加上一些动画效果,让页面看起来更加炫酷,需要的朋友可以参考下
    2023-07-07
  • js拆分字符串并将分割的数据放到数组中的方法

    js拆分字符串并将分割的数据放到数组中的方法

    这篇文章主要介绍了js拆分字符串并将分割的数据放到数组中的方法,涉及javascript中split方法及数组的操作技巧,需要的朋友可以参考下
    2015-05-05

最新评论