JavaScript数组去重全攻略:从基础到封装

作者:闭包旅人

时间:2026-10-30

浏览:172

本文系统总结了JavaScript中实现数组去重的多种方案,涵盖双重循环、indexOf、sort排序、filter过滤以及Set/Map数据结构等常用技巧。文章进一步演示如何结合排序状态与回调函数,封装一个高复用性的通用去重API,适用于不同业务场景下的数据处理需求。

文章目录

前言

在面试场景中,面试官常会要求对给定数组进行去重处理。除了使用Set这一常见手段外,你是否还能列举其他实现方式?能否独立封装一个具备复用价值的去重接口?回顾过往经历,面对此类问题时,往往难以迅速给出多种解决方案。本文将梳理针对该经典面试题的各种可行解法。

数组去重

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检测结果数组中是否已包含当前元素。若未找到(返回-1),则将其加入结果数组,从而完成去重。

在上述代码基础上,可进一步优化,将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,判断其与当前值是否一致,从而筛选出唯一值。

注意:由于数组排序方法无法区分数字与字符串类型,使用此方法前需确保数组内元素类型一致,否则可能导致非预期结果。

4. 使用 filter

既然涉及排序,直接使用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数组去重的资料请关注本站其它相关文章!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章