微博客

在web前端面试题中,经常会出现这样一道题目:“请写一段函数,剔除数组中重复的元素。”

于是今天认真想了想,出了两个方案,性能方面都不理想,于是在大漠的qq群里面请教,网友Dino出了个方案,经过测试,性能很好,于是一起总结下:

测试环境:window 7 -firefox 19--firebug

方案一:obj属性判断除重法--性能最好,推荐!(虽然多了个obj,但比后面两个方案快多了)

var aRandomNumberItems = function (n){
        var result = [];
        for (var i = 0;i < n; i++){
            var nRandom = Math.ceil(Math.random()*50);
            result.push(nRandom);
        }
        return result;
    };
    var aRandomNumberItem1 = aRandomNumberItems(50000);
    console.time('time3');
    Array.prototype.distinct3 = function () {
        var arr = [],
            obj = {},
            len = this.length,
            result;
        for (var i = 0; i < len; i++) {
            result = this[i];
            if (!obj[result]) {
                obj[result] = '1';
                arr.push(result);
            }
        }
        return arr;

    }
    
    aRandomNumberItem1.distinct3();

    console.timeEnd('time3');//结果为4ms
}

方案二:在方案一的基础上把函数内的数组for()循环修改为了forEach() 循环,反而效率下降了。而且IE6、7、8不支持forEach()函数,尽管我们可以给他们打补丁来实现兼容

var aRandomNumberItems = function (n){
        var result = [];
        for (var i = 0;i < n; i++){
            var nRandom = Math.ceil(Math.random()*50);
            result.push(nRandom);
        }
        return result;
    };
    var aRandomNumberItem1 = aRandomNumberItems(50000);
    console.time('time');
    Array.prototype.distinct = function () {
        var arr = [],
            obj = {};
        this.forEach(function (value,index){
            if (!obj[value]){
                obj[value] = 1;
                arr.push(value);
            }
        })
            
        return arr;

    }

aRandomNumberItem1.distinct();

    console.timeEnd('time');//结果为28ms

 方案三:sort排序循环比对法---性能不太好(sort()性能不太好,循环比对次数也多,整体慢)

    var aRandomNumberItems = function (n){
        var result = [];
        for (var i = 0;i < n; i++){
            var nRandom = Math.ceil(Math.random()*50);
            result.push(nRandom);
        }
        return result;
    };
    var aRandomNumberItem1 = aRandomNumberItems(50000);
    console.time('time1')
    Array.prototype.distinct1 = function () {
        this.sort(function (a,b) {
            return a-b;
        })
        
        for (var i = 0; i < this.length-1; i++){
            if (this[i] === this[i+1]){
                this.splice(i+1,1);
                i--;
            }
        }
        return this;
    }
    aRandomNumberItem1.distinct1();
    console.timeEnd('time1');//结果为1819ms,其中sort占用500ms

方案四:嵌套循环比对法--性能太差(浏览器直接卡死了)

    var aRandomNumberItems = function (n){
        var result = [];
        for (var i = 0;i < n; i++){
            var nRandom = Math.ceil(Math.random()*50);
            result.push(nRandom);
        }
        return result;
    };
    var aRandomNumberItem1 = aRandomNumberItems(200);

    console.time('time2');
    Array.prototype.distinct2 = function () {
        for (var i = 0; i < this.length-2; i++){
        var nNum1 = this[i];
        for (var j = i + 1;j <this.length-1; j++){
            var nNum2 = this[j];
            if (nNum1 === nNum2){
                this.splice(j,1);
                i--;
            }
        }
    }

    }
    aRandomNumberItem1.distinct2();

    console.timeEnd('time2');//当数组length为50000的时候,浏览器直接卡死了,当length为200时,结果为1834ms,性能太差

 虽然方案一的测试效果已经很理想了,但是函数中必经还有个冗余对象obj,应该还能优化,个人水平有限,各位看官如果还有比方案一更好的方案,记得分享一下呀!

posted on 2013-04-05 15:58  飞鸟42  阅读(461)  评论(2)    收藏  举报