javascript之数组去重

双重循环

  • 双重循环是利用两个for循环来实现数组去重的,兼容性最好,可是若是数组的数据过于庞大的时候,性能不佳。
function unique(array) {
    let result = []
    for(var i = 0; i < array.length; i++){
        for(var j = 0; j < result.length; j ++){
            if (array[i] === result[j]) {
                // 若是result中有和array[i]相同的项,直接跳出循环再也不继续,而且j不会自增
                // j 不自增,就意味着,j不会等于result.length,下面的if语句就不会执行
                break
            }
        }
        // 若是result中没有与array[i]相同的项,那么第二层for循环完毕以后,j === result.length
        // 并将这轮循环的 array[i] push 到result中
        if (j === result.length) {
            result.push(array[i])
        }
    }
    return result
}
复制代码

使用indexOf()方法

  • 经过indexOf()方法,来判断数组中是否存在指定的值,找到以后返回下标,没有找到则返回 -1
function unique(array) {
    var res = []
    for (var i = 0; i < array.length; i ++){
        if (res.indexOf(array[i]) === -1) {
            res.push(array[i])
        }
    }
    return res
}
复制代码

ES5的filter()方法结合indexOf()方法去重

  • filter()方法能够过滤数组,返回过滤后的数组,且不改变原数组
function unique(array) {
    return array.filter((item, index, self) => self.indexOf(item) === index)
    // [1,1,1,1].indexOf(1)返回的是第一个'1'的下标0,不会再查询第一个 '1' 后面的元素了。
    // 在这里,self.indexOf(item)每次返回的都是下标0,除了第一个元素(index = 0),以后等式都不成立了。
}
复制代码

经过对象的key-value来实现去重

  • 对象有个hasOwnProperty()方法,用来查找对象是否含有某个key,返回布尔值
  • 注意,若是咱们定义一个以下的对象,结果会是什么呢 ?
var obj = {
    1: 'number1',
    '1': 'string1'
}
复制代码
  • 答案是字符串'1'会将数字1覆盖,知道这个小细节以后,咱们再来实现去重的方法。
function unique(array) {
    var obj = {}
    return array.filter((item, index, self) => {
        // 若是对象中没有找到 typeof item + item, 则向其添加一个 key: typeof item + item,value设置为true,表示将item过滤出来。
        // value能够随便设置,除了0,'',undefined等等这些会转化成false值的值
        return obj.hasOwnProperty(typeof item + item) ? false : obj[typeof item + item] = true
    })
}
复制代码

最后咱们能够采用ES6中的一种新的数据结果Set,它相似于数组,可是它的项都是惟一的,没有重复的值。

Set自己是一个构造函数,用来生成 Set 数据结构。

  1. Set 结构的实例有如下属性。数组

    • Set.prototype.constructor:构造函数,默认就是Set函数。
    • Set.prototype.size:返回Set实例的成员总数。
  2. Set 实例的方法分为两大类:操做方法(用于操做数据)和遍历方法(用于遍历成员)。bash

    • add(value):添加某个值,返回 Set 结构自己。
    • delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
    • has(value):返回一个布尔值,表示该值是否为Set的成员。
    • clear():清除全部成员,没有返回值。
    • keys():返回键名的遍历器
    • values():返回键值的遍历器
    • entries():返回键值对的遍历器
    • forEach():使用回调函数遍历每一个成员
var uniqueArr = new Set([1,2,3,1,'1','a','a'])

>>>uniqueArr
<<< Set(5) {1, 2, 3, "1", "a"}

>>> uniqueArr instanceof Array
<<< false
复制代码
  • 能够看到,返回的结果是Set数据结果,那么如何返回一个数组呢?这就要用到ES6提供的另外一个数组方法了
  • Array.from(obj, fn, context)方法将一个类数组对象或者可遍历对象转换成一个真正的数组,它能够接受三个参数,第一个是须要转化的对象,第二个是一个函数,对象的每一项都会执行这个函数,返回处理后的项,context指定执行fn的this对象

理解用法以后,咱们再来看一下如何使用Set来实现数组去重

function unique(array) {
    return Array.from(new Set(array))
}
复制代码

固然也能够不使用Array.from()方法,使用ES6 '...' 扩展运算符

function unique(array) {
    return [...new Set(array)]
}

// 咱们能够简化一下这个函数

var unique = (array) => [...new Set(array)]
复制代码

总结:咱们看到,数组去重的方式有不少,但以上都是在处理基本数据类型,可是若是碰到数组中存在对象的时候,还须要另当别论。看下以下的例子:

>>> NaN === NaN
<<< false

>>> NaN == NaN
<<< false

>>> {} == {}
<<< false

>>> {} === {}
<<< false

>>> undefined == undefined
<<< true

>>> undefined === undefined
<<< true

>>> null == null
<<< true

>>> null === null
<<< true
复制代码
相关文章
相关标签/搜索