资讯专栏INFORMATION COLUMN

最全的数组去重方法对比

BlackHole1 / 3106人阅读

摘要:本文最早发布于,为原创常规方法两种数组深拷贝,为不了影响原来的数组第一种方法常用但是有坑碰到这种情况就出问题了第二种方法使用,方法返回的结果并不一定是升序,主要目的是将重复的数字排到一起使用的方法两种简洁优雅版奇技淫巧更新看到评论

本文最早发布于csdn,为原创

常规方法两种
let json = arr => {
    let res = [],
        obj = {};
    arr.forEach(value => {
        let key = typeof(value) + value;
        !obj.hasOwnProperty(key) && (res.push(value), obj[key] = 1);
    })
    return res;
}

let sort = arr => {
    //数组深拷贝,为不了影响原来的数组
    let newArr = arr.concat();
    newArr.sort();
    for (var i = newArr.length; i > 0; i--) {
        if ( newArr[i] === newArr[ i - 1 ] ) { // use == if "2" eq 2, else ===
            newArr.splice( i, 1 );
        }
    }
    return newArr;
}

第一种方法常用但是有坑

console.log(unique([ new String(1), new Number(1) ]))
//[String]0: String0: "1"length: 1__proto__: String[[PrimitiveValue]]: "1"length: 1__proto__:Array[0]

碰到这种情况就出问题了

第二种方法使用sortsort方法返回的结果并不一定是升序,主要目的是将重复的数字排到一起

使用ES5的indexOf方法两种
let foreach = arr => {
    arr.forEach(value => {
        res.indexOf(value) == -1 && res.push(value);
    }, res = [])
}
let unique = arr => {
    let res = [];
    arr.forEach(function(value) {
        (res.indexOf(value) == -1) && res.push(value);
    })
    return res;
}
let arr = [1, 1, 2, 2];
unique3(arr);
console.log(res);
简洁优雅版
let filter = arr => { return arr.filter(function (value, index, array) { return index <= array.indexOf(value);}); };
es6奇技淫巧

2016.7.7更新
看到评论提醒的方法

let array = Array.from(new Set([1, 1, 1, 2, 3, 2, 4]));
console.log(array);
// => [1, 2, 3, 4]

补充说明,from方法现在浏览器支持程度不太好,另外经测试,性能也不具有优势

性能对比

2016.7.12更新,最近发现了一篇文章进行性能测试,觉得很赞,以后测性能就用这个了
benchmark地址

let benchmark = require("benchmark");
let suit = new benchmark.Suite;
let arr = [1, 1, 1, 2, 3, 2, 4];
let es6 = arr => {
    let array = Array.from(new Set(arr));
};

let filter = arr => { 
    arr.filter((value, index, array) => { return index <= array.indexOf(value);}); 
};

let json = arr => {
    let res = [],
        obj = {};
    arr.forEach(value => {
        let key = typeof(value) + value;
        !obj.hasOwnProperty(key) && (res.push(value), obj[key] = 1);
    })
    return res;
}

let sort = arr => {
    //数组深拷贝,为不了影响原来的数组
    let newArr = arr.concat();
    newArr.sort();
    for (var i = newArr.length; i > 0; i--) {
        if ( newArr[i] === newArr[ i - 1 ] ) { // use == if "2" eq 2, else ===
            newArr.splice( i, 1 );
        }
    }
    return newArr;
}

let foreach = arr => {
    arr.forEach(value => {
        res.indexOf(value) == -1 && res.push(value);
    }, res = [])
}

suit.add("es6", function() {
    es6(arr);
}).add("filter", function() {
    filter(arr);
}).add("json", function() {
    json(arr);
}).add("sort", function() {
    sort(arr);
}).add("foreach", function() {
    foreach(arr);
}).on("cycle", function(event) {
    console.log(String(event.target));
}).on("complete", function() {
    console.log("Fastest is " + this.filter("fastest").map("name") + "
 slowest is " + this.filter("slowest").map("name"));
}).run({"async": true});

在teminal运行node test.js得到如下结果

$ node 数组去重方法及对比.js
es6 x 275,353 ops/sec ±4.87% (63 runs sampled)
filter x 703,449 ops/sec ±1.49% (89 runs sampled)
json x 238,876 ops/sec ±5.24% (72 runs sampled)
sort x 217,857 ops/sec ±4.58% (64 runs sampled)
foreach x 915,368 ops/sec ±3.84% (65 runs sampled)
Fastest is foreach
slowest is sort
总结

以上所有方法都不会出现将1和"1"视作一起去重的情况,除开第一种,其他的方法也能区分开[new String(1), new Number(1)],这里的方法已经是比较全,和其他博客比起来只有一些实现上的差异,总体方法思想是一样的

参考资料

一行代码实现数组去重(ES6)
从 JavaScript 数组去重谈性能优化
js对象的hasOwnProperty为什么比数组的indexof方法在性能上高的多?
使用Benchmark.js和jsPerf分析代码性能
源代码github地址

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79933.html

相关文章

  • JavaScript数组去重(12种方法,史上最全

    摘要:数组去重,一般都是在面试的时候才会碰到,一般是要求手写数组去重方法的代码。如果是被提问到,数组去重的方法有哪些你能答出其中的种,面试官很有可能对你刮目相看。数组去重的方法一利用去重中最常用不考虑兼容性,这种去重的方法代码最少。 数组去重,一般都是在面试的时候才会碰到,一般是要求手写数组去重方法的代码。如果是被提问到,数组去重的方法有哪些?你能答出其中的10种,面试官很有可能对你刮目相看...

    rozbo 评论0 收藏0
  • 好像不是最全数组去重方法

    摘要:最简单粗暴地方式,两重循环两个因为两个因为排序,如果相同就会挨着先放数组第一个元素无法判断对象对象数组去重方法补充我想说一下与相同点他们都是用来遍历数组的。不同点能有返回值,没有返回值。 这一篇文章,我们讲解一下数组去重。 1.最简单粗暴地方式,两重for循环 let arr = [9, 5, 6, 5, 1, 1, true, 5, true]; for (var i = 0; i ...

    AnthonyHan 评论0 收藏0
  • js数组去重几种方法

    摘要:三种方法利用判断新数组中实际上也是使用的类似的传入数组如果当前数组的第已经保存进了临时数组,那么跳过,否则把当前项到临时数组里面利用判断旧数组结果数组如果当前数组的第项在当前数组中第一次出现的位置不是,那么表示第项是重复的,忽略掉。 三种方法 利用indexOf判断新数组 underscore.js中实际上也是使用的类似的indexOf //传入数组 functio...

    mykurisu 评论0 收藏0
  • 数组去重各种方法速度对比

    摘要:首先需要一个自动生成数组的函数自动生成数组的函数执行上面函数,的到的数组长度为,因为执行速度很快,只有长度很大时,才能看到各个方法的执行速度的差别注意到不能简单的用赋值,否则改变后,到也相应改变了七个相同的数组并且数组长度要足够大才能对比出 首先需要一个自动生成数组的函数 // 自动生成数组的函数 function randomArr (n) { let...

    1treeS 评论0 收藏0
  • 史上最全 Python 3 类型转换指南

    摘要:支持转换为类型的,仅有,其他类型均不支持。如果中含有正负号数字和小数点以外的字符,则不支持转换。转换时,会自动添加虚数部分并以表示。转换会直接完全转换。转换列表,会取每个字节的十进制值并组合成列表转换为比较简单。 int 支持转换为 int 类型的,仅有 float、str、bytes,其他类型均不支持。 float -> int 会去掉小数点及后面的数值,仅保留整数部分。 int(-...

    libxd 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<