真钱捕鱼array_unique

引进阅读:JavaScript学习笔记之数组的增、删、改、查

主意生机勃勃:双重遍历

JavaScript学习笔记之数组求和方法

重新遍历是最容易想到的去重方案:

JavaScript学习笔记之数组随机排序

  1. 营造四个新的数组存放结果
  2. for循环中年老年是从原数组收取三个成分,用那个成分循环与结果数组相比较
  3. 若结果数组中并未有该因素,则存到结果数组中

    Array.prototype.unique=function(){

    // 构建一个新数组,存放结果 
    var newArray = [this[0]];
    for (var i = 0; i<this.length; i++){
        var repeat = false;
        for(var j=0;j<newArray.length;j++){
            if(this[i]===newArray[j]){
                repeat=true;
                break;
            }
        }
        if(!repeat){
            newArray.push(this[i]);
        }
    }
    return newArray;
    

    }

话说面试常会赶下边试官会问JavaScript达成数组去重的难题,方今恰幸好读书有关于JavaScript数组有关的学问,趁当时机整理了有个别关于于JavaScript数组去重的不二等秘书诀。

  • 亮点:思路轻松、轻松完毕,用于去重的可比部分是温馨编辑达成(this[i]==newArray[j])。能够针对具体意况加以特殊管理。
  • 症结:时间复杂度高,品质差。

上面这么些数组去重的法子是自个儿征集和整合治理的,如有不对希望指正文中不对之处。

以上面那么些测验案例开展相比较:

再一次循环去重

function test () { 
    var arr = []; 
    for (var i = 0; i < 1000000; i++) { 
        arr.push(Math.round(Math.random(i) * 10000)); 
    } 
    doTest(arr, 1); 
} 
function doTest(arr, n) { 
    var tStart = (new Date()).getTime(); 
    var re = arr.unique(); 
    var tEnd = (new Date()).getTime(); 
    console.log('双重循环去重方法使用时间是:' + (tEnd - tStart) + 'ms'); 
    return re; 
} 
test();

其生龙活虎措施运用了七个for循环做遍历。整个思路是:

在Chrome调整台北测量检验方法生龙活虎,耗时为:4006ms

构建四个空数组用来存放去重后的数组

方法二:排序遍历去重

先使用sort()艺术对原数组做一个排序,排完序之后对数组做遍历,何况检查数组中的第i个成分与结果数组中最终三个因素是不是相通。若是不一致,则将成分放到结果数组中。

Array.prototype.unique = function () { 
    // 原数组先排序 
    this.sort(); 
    // 构建一个新数组存放结果 
    var newArray = []; 
    for (var i = 1; i < this.length; i++) { 
    // 检查原数组中的第i个元素与结果中的最后一个元素是否相同 
    // 因为排序了,所以重复元素会在相邻位置 
        if(this[i] !== newArray[newArray.length - 1]) { 
        // 如果不同,将元素放到结果数组中 
            newArray.push(this[i]); 
        } 
    } 
    return newArray; 
}
  • 优点:速度快,只需要700ms
  • 症结:去重后的数组会做排序、去重后的数组,与数字相通的数字字符不恐怕区分,譬如'12'12

外部的for循环对原数组做遍历,每趟从数组中抽出八个因素与结果数组做对譬假若原数组抽取的要素与结果数组成分雷同,则跳出循环;反之则将其存放到结果数组中

格局三:对象键值对法

这种方法是采纳了对象的key不得以重新的特征来进展去重。

  1. 创制八个JavaScript对象及新数组
  2. 使用for循环遍历原数组,每一次抽取三个因素与JavaScript对象的键做比较
  3. 借使不含有,将存入对象的要素值推入到结果数组中,何况将存入对象的该key的value设为1

    Array.prototype.unique=function() {

    var ret = [];
    var len = this.length;
    var tmp = {};
    for(var i=0; i<len; i++){
        if(!tmp[this[i]]){
            tmp[this[i]] = 1;
            ret.push(this[i]);
        }
    }
    return ret;
    

    }

  • 优点:速度快,只需要10ms
  • 症结:去重后的数组,与数字相符的数字字符不能区分,举个例子'12'12,因为对象key只可以为字符串;不或然管理复杂数据类型,比方对象(因为对象作为key会产生[object Object]);特殊数据,举例'proto'会挂掉,因为tmp对象的'proto'属性不能被重写

依照上边提到的症结,有人提议了以下的改正方式:

Array.prototype.unique=function() {
    var ret = [];
    var len = this.length;
    var tmp = {};
    var tmpKey;
    for(var i=0; i<len; i++){
        tmpKey = typeof this[i] + JSON.stringify(this[i]);
        if(!tmp[tmpKey]){
            tmp[tmpKey] = 1;
            ret.push(this[i]);
        }
    }
    return ret;
}

那个改正措施能够弥补上述提到的老毛病,然则品质统筹下落,去重速度达到了500ms左右,且内部存款和储蓄器占用较高,但仍是逐条方案中最快的。

Array.prototype.unique1 = function () {// 构建一个新数组,存放结果var newArray = [this[0]];// for循环,每次从原数组中取出一个元素// 用取出的元素循环与结果数组对比for (var i = 1; i < this.length; i++) {var repeat = false;for (var j=0; j < newArray.length; j++) {// 原数组取出的元素与结果数组元素相同if(this[i] == newArray[j]) {repeat = true;break;}}if {// 如果结果数组中没有该元素,则存放到结果数组中newArray.push;}}return newArray;}

方法四:Map Key

ES2016中增添了Map这种新的数据类型,能够把它想象成key类型未有节制的靶子,它的存取使用单独的get(State of Qatar、set(卡塔尔接口。与历史观的指标比较,Map的key在利用中未有范围。

Array.prototype.unique=function() {
    var ret = [];
    var len = this.length;
    var tmp = new Map();
    for(var i=0; i<len; i++){
        if(!tmp.get(this[i])){
            tmp.set(this[i], 1);
            ret.push(this[i]);
        }
    }
    return ret;
}
  • 优点:试行进程快,43ms
  • 症结:包容性不高。

假使大家有多少个如此的数组:

方法五:Set

除开Map以外,ES二零一六还引进了生龙活虎种叫作Set的数据类型。它区别意再一次成分现身。

Array.prototype.unique=function(){
    var set = new Set(this);
    return Array.from(set);
}
  • 可取:代码轻便,试行进程极快,600ms左右。
  • 破绽:宽容性不高。
var arr = [1,2,3,4,'a','b',1,3,4,56,32,34,2,'b','c',5,'1',`2`];arr.unique1(); // [1, 2, 3, 4, "a", "b", 56, 32, 34, "c", 5]

总结

去重的章程未有最不利的,也远非最优,应该切实难题具体深入分析,遵照实际情状实行抉择正确的不二诀要。

请使用手提式有线电话机"扫一扫"x

据称这种方法比较耗费时间,费品质。轻易做个测量检验:

function test () {var arr = [];for (var i = 0; i < 1000000; i++) {arr.push(Math.round * 10000));}doTest;}function doTest {var tStart = ;var re = arr.unique1();var tEnd = ;console.log('双重循环去重方法使用时间是:' +  + 'ms');return re;}test();

在Chrome调控器运维方面包车型客车代码,测验再度循环去重所费时间:11031ms。

地点的方法能够采用forEach方法模拟达成:

function unique1() {var newArray = [];this.forEach {if (newArray.indexOf {newArray.push;return newArray;}

由此unique1.apply或unique1.call调用。可是这种措施成效要快得多,同样的上面测试代码,所费时间5423ms,差相当少快了大要上。

排序遍历去重

先采用sort(卡塔尔国方法对原数组做一个排序,排完序之后对数组做遍历,何况检查数组中的第i个要素与结果数组中最后二个成分是不是意气风发律。假如不一样,则将成分放到结果数组中。

Array.prototype.unique2 = function () {// 原数组先排序this.sort();// 构建一个新数组存放结果var newArray = [];for (var i = 1; i < this.length; i++) {// 检查原数中的第i个元素与结果中的最后一个元素是否相同// 因为排序了,所以重复元素会在相邻位置if(this[i] !== newArray[newArray.length - 1]) {// 如果不同,将元素放到结果数组中newArray.push;}}return newArray;}

var arr = [1,2,3,4,'a','b',1,3,4,56,32,34,2,'b','c',5,'1','2'];arr.unique2(); // ["1", 1, 2, "2", 3, 32, 34, 4, 5, 56, "a", "b", "c"]

去重后的数组会做排序,首倘若因为原数在去重前做了排序

去重后的数组,与数字肖似的数字字符不能够区分,比如'1'和1

利用相符的章程,测验所费时间:1232ms。

返回列表