zoukankan      html  css  js  c++  java
  • 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方法。

  • 相关阅读:
    康复计划
    Leetcode 08.02 迷路的机器人 缓存加回溯
    Leetcode 38 外观数列
    Leetcode 801 使序列递增的最小交换次数
    Leetcode 1143 最长公共子序列
    Leetcode 11 盛水最多的容器 贪心算法
    Leetcode 1186 删除一次得到子数组最大和
    Leetcode 300 最长上升子序列
    Leetcode95 不同的二叉搜索树II 精致的分治
    Leetcode 1367 二叉树中的列表 DFS
  • 原文地址:https://www.cnblogs.com/zhangbob/p/9294619.html
Copyright © 2011-2022 走看看