笔者在做项目的时候遇到一个问题,需要对数组进行去重操作。在网上找到了各种解决的方法,整理了一下,简单分析一下每种的优缺点。
第一种方法遍历循环 第一种方法也是最一般、最常用的办法,使用数组的indexOf()
方法。
let arr = [1 ,'1' ,2 ,'2' ,1 ,2 ,'x' ,'y' ,'f' ,'x' ,'y' ,'f' ];function unique1 (arr ){ let result = [arr[0 ]]; for (let i = 1 ; i < arr.length ; i++) { let item = arr[i]; if (result.indexOf (item) == -1 ){ result.push (item); } } return result; }console .log (unique1 (arr));
但是indexOf方法内部实现也是去遍历数组知道找到目标为止,如果待去重的数组很长且重复的元素少,则会耗费了大量的时间。
第二种方法存放Hash对象 第二种方法是将数组所有的元素转变成对象的键名,利用对象键名的不可重复的特性来去重。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 let arr = [1 ,'1' ,2 ,'2' ,1 ,2 ,'x' ,'y' ,'f' ,'x' ,'y' ,'f' ];function unique2 (arr ){ let result = []; let obj ={}; for (let i =0 ;i<arr.length ;i++){ let item = arr[i]; if (!obj[item]){ result.push (item); obj[item] = 1 ; } } return result; }console .log (unique2 (arr))
在时间消耗上来看,这种方法比第一种方法要快很多,因为从对象中取属性值消耗的时间几乎可以不计,但是存在以下两个问题:
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
由于需要存放Hash对象,因此在内存占用上比第一种方法会多占用更多的内存空间,就是所谓的空间换时间。
从上面的排序结果我们会发现一个问题,’12’不在结果中。因为在键名中,String类型的’12’和Number类型的12对于Hash对象来说都是一样的。
第三种方法排序比较 第三种方法利用数组原生的sort()
方法,将数组先进行排序,排序后比较相邻两个元素的值。
let arr = [1 ,'1' ,2 ,'2' ,1 ,2 ,'x' ,'y' ,'f' ,'x' ,'y' ,'f' ];function unique3 (arr ) { let result = [arr[0 ]]; arr = arr.sort (); for (let i = 1 ; i < arr.length ; i++) { let item = arr[i]; if (item !== result[result.length - 1 ]) { result.push (item) } } return result; }console .log (unique3 (arr))
谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里
这种方法比indexOf()
消耗的时间要短,比存放Hash对象占用的内存要小,算是一种折中两者的方法。但是也存在一个问题,就是去重后的数组的顺序发生了改变。
第四种方法利用Set类型 如果你开发环境支持ES6,这个方法是最简洁的。
let arr = [1 ,'1' ,2 ,'2' ,1 ,2 ,'x' ,'y' ,'f' ,'x' ,'y' ,'f' ];function unique4 (arr ){ return Array .from (new Set (arr)); }console .log (unique4 (arr));