JavaScript数组去重方法总结

数组不像对象和hash有惟一的标志特征(key)。因此,数组去重的核心就是【1】数组内元素互相比较,而后放入新的数组中。【2】参照对象构建一个惟一的特征标志,而后放入新数组中。如下就是依照这种思路产生的方法。【3】数组中含对象的去重方式我采用使用JSON.stringify()将对象转换成JSON字符串进行比较的方式。数组

1.最基础的去重:双重遍历

  • 双重遍历的核心就是依据【1】,经过拿出一个元素和剩下的元素依次比较,若是所有不相等则证实此元素为惟一。
let a=[{a:1},{b:2},{c:3},{a:1},{d:2}]
let c=[1,2,3,4,5,6,1,2,3]
function unique(arr){
    let b=[]
    for(let i=0;i<arr.length;i++){
        let unexit=true
        for(let j=i+1;j<arr.length;j++){
            if(JSON.stringify(arr[i])===JSON.stringify(arr[j])){
                unexit=false
                break
            }
            else{
                unexit=true
            }
        }
        if(unexit){
            b.push(arr[i])
        }
    }
    return b
}
复制代码
  • 关于数组中存在对象,是采用JSON.stringify()转换成JSON字符串进行的比较,后续再也不叙述。双重遍历的缺点是复杂度过高。
  • 上面的代码去重获得的结果的顺序会改变,因此若是想要顺序按照原有顺序,数组在进行去重时建议从新申明一个新的数组(var new=old.reverse())获得一个新的相反的数组,最后再使用reverse()。之因此新建数组而不是直接取反是由于:reverse()会修改原数组。

2.Array.prototype.sort():相邻元素去重

相邻元素去重的核心在于Array.sort()可以对数组进行排序。这样相等的数组就会在相邻的位置,经过比较相邻的元素就能够起到去重的做用【1】。bash

let c=[1,2,3,4,5,6,1,2,3]
function unique(arr){
    let Arr=arr.sort()
    let b=[]
    for(let i=0;i<Arr.length;i++){
        if(Arr[i]!==Arr[i+1]){
            b.push(Arr[i])
        }
    }
    return b
}
复制代码
  • Array.prototype.sort()方法可使用array.sort((a,b)=>{a.key-b.ky})进行对象的排序,前提是数组中的对象存在相同的key值。

3.Object.keys():存在惟一性

在一个对象里面key值是惟一的,因此经过遍历数组给每一个数组一个标志,经过标志去重【2】数据结构

let a=[{a:1},{b:2},{c:3},{a:1},{d:2}]
let c=[1,2,3,4,5,6,1,2,3]
function unique(arr){
    let b=[]
    let hash={}
    for(let i=0;i<arr.length;i++){
        if(!hash[JSON.stringify(arr[i])]){
            hash[JSON.stringify(arr[i])]=true
            b.push(arr[i])
        }
    }
    return b
}

复制代码

4.双重遍历去重改良之:indexOf

  • 双重遍历的思路咱们都知道,先拿出一个元素,而后使用循环再次遍历数组去一一比较。若是有一个方式可以让咱们再也不遍历一遍数组,那么复杂度相对而言会减小一点。
  • indexOf 方法返回给定元素在数组中第一次出现的位置,若是没有出现则返回-1。首先咱们新建一个空数组(arry),若是:arry.indexOf(数组元素)===-1,那么咱们就能够知道arry中不存在元素。
let c=[1,2,3,4,5,6,1,2,3]
function unique(arr){
    let b=[]
    for(let i=0;i<arr.length;i++){
        if(b.indexOf(arr[i])==-1){
            b.push(arr[i])
        }
    }
    return b
}
复制代码
  • indexOf 方法可返回某个指定的字符串值在字符串中首次出现的位置。因此对象不适用,由于对象转为字符串就都会变成{object,object},没法比较。

5.循环遍历之:map()/forEach()

  • map()和forEach()均可以实现遍历数组。因此以上的方法均可以用map()、forEach()改写。下面我只简单的改写一个,其余的改写方式参照便可。
let c=[1,2,3,4,5,6,1,2,3]
function unique(arr){
    let b=[]
    arr.forEach(res=>{
        if(b.indexOf(res)==-1){
            b.push(res)
        }
    })
    return b
}
复制代码

6.ES6:Set数据结构

Set数据相似于数组,可是成员的值都是惟一的,没有重复的值。它能够接收一个数组,类于:let a=[1,2,3,1,2] Set(a)=>1,2,3 因此可使用Set()实现去重。ui

let c=[1,2,3,4,5,6,1,2,3]
function unique(arr){
    let b=new Set(arr)
    let c=Array.from(b)
    return c
}
复制代码
  • Set去重不适用于含对象的数组,由于Set的去重参照的是(===),数组中的元素对象,虽然可能数值相等,可是地址不相等。因此Set没法实现去重。

7.总结

  • 实现数组的去重,要么经过元素对比,要么设置特殊标志识别。元素对比的思路有2种:一种是和原数组一一对比;另外一种和新的数组对比。
  • 若是要实现含对象的数组去重,通常使用遍历的方式,包括使用遍历类的方法(map、forEach、reduce等)。像Set、sort等经过改变数组的方式通常是不可行的。
相关文章
相关标签/搜索