5种数组去重方法的性能对比

数组去重是老生常谈的话题,在es5之前的标准中,是没有直接提供数组去重方法的,单我们在工作和面试中经常会遇到数组去重的考题,为此,我在这里总结了数组去重的4个方法,并对他们的性能做了对比。

//以下为es5方法

    //利用sort进行排序,再对数组遍历,每个元素和他后面的元素比较,如果不相等就push进新的数组,最后输出
    function sortDelete(array) {
        let now = Date.now();
        array.sort((a,b) =>  {return a - b});
        let i = 0,
        newArray = new Array(),
        l = array.length;

        for (; i < l; i++) {
            if (!i || array[i] !== array[i - 1]) {
                newArray.push(array[i]);
            }
        }

        return {
            array: newArray,
            duration: Date.now() - now
        };

    }

    let obj = sortDelete(array);
    console.log(obj.array,"排序去重耗时:" + obj.duration + "ms");


    //在循环里对新数组查询,如果没有找到原数组的元素,则push元素到新数组。
    function indexofDelete(array) {
        let now = Date.now();
        let newArray = [];
        let i = 0,
        l = array.length;

        for (;i < l; i++) {
            if (newArray.indexOf(array[i])  === -1) {
                newArray.push(array[i]);
            }
        }

       return {
            array: newArray,
            duration: Date.now() - now
        }
    }

    let obj1 = indexofDelete(array);
    console.log(obj1.array,"indexof去重耗时:" + obj1.duration + "ms");


    //做两层循环,第一层遍历原数组,第二层遍历新数组,如果找到两个相同的元素,则终止第二层循环,第一层循环进入下次循环;当第二层循环到最后一个元素任然找不到新数组里有相同的元素,则push元素到新数组,这个方法接近indexOf的实现方式,所以和使用indexOf的性能几乎一样
    function dobuleFor(array) {
        let now = Date.now(),
        newArray = [],
        i = 0,
        l = array.length;

        for (; i < l; i++) {
            for (let m = 0; m < newArray.length; m++) {
                if (array[i] === newArray[m]) {
                    break;
                }

                if (m == newArray - 1) {
                    newArray.push(array[i]);
                }
            }
        }

        return {
            array: newArray,
            duration: Date.now() - now
        }
    }

    let obj2 = indexofDelete(array);
    console.log(obj2.array,"双循环去重耗时:" + obj2.duration + "ms");

//使用array对象的filter方法,该方法接受可以接受一个回调函数,满足函数条件的元素会进入新的数组,回调函数接受三个参数,分别是数组元素,对应的建和数组,该方法不对原数组操作,返回过滤后的数组;我们在这里indexof原数组,利用indexof查找到一个匹配值就会停止的特性,我们将返回值和当前index作比较,形同的话说明,当前值在以前查询中没有出现过,返回true,添加进新的数组。
    function filterWord(array) {
        let now = Date.now();
        let newArray = array.filter((item,index,array) => {
            return array.indexOf(item) === index;
        });

        return {
            array: newArray,
            duration: Date.now() - now
        }
    }

    let obj3 = filterWord(array);
    console.log(obj3.array,"过滤去重耗时:" + obj3.duration + "ms");


    //es6

    //es6的Sort()构造函数可传入一个类数组对象或支持map方法的值,它返回一个没有重复项的数组,但是不对NAN做去重
    function byES6Set(array) {
        let now = Date.now();
        let newArray = (array) => {return new Set(array)}
         return {
            array: newArray,
            duration: Date.now() - now
        }
    };

    let obj4 = byES6Set(array);
    console.log(obj3.array,"set去重耗时:" + obj4.duration + "ms");

我测试的时候添加了1w+个数组元素的数组,性能测试如下图:

可以看到,使用es6的Sort数据结构是最快的,而indexOf和双层循环方法也很快,而且两者性能一样,filter方法去重很慢,在没做代码编译的情况下,推荐使用indexOf方法。

原文地址:https://www.cnblogs.com/zhangbob/p/9294619.html