关于JavaScript数组去重的一些理解汇总
前言
做前端开发几年,在项目中用到数组去重的机会倒不是很多,但是在面试的时候却经常被问到,个人理解,这道题真正考的是对JavaScript的基础的掌握,因为有很多种方式可以做到。这次就根据这道题,将相关的知识理解透彻。
一、ES6中的newSet方式
先看看MDN上对Set的描述:
Set对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
Set对象是值的集合,你可以按照插入的顺序迭代它的元素。Set中的元素只会出现一次,即Set中的元素是唯一的。
关键字:任何类型都可以存储、存储进来的值都是唯一的,这样就可以做到先把数组中重复的数据去掉。
constlist1=[1,2,3,7,11,56,3,2,4,5] constlist2=newSet(list1) console.log(list2)
看一下返回的结果:
由结果可知,返回了一个可迭代的Set对象,此时还需要把Set对象转为数组。此时可以用到
Array.from()。
**Array.from()**方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例.
刚好newSet()返回的就是一个可迭代的对象。
constlist3=Array.from(newSet([null,null,undefined,12,undefined,7,2,1,22,2,functiona(){},functiona(){},{},{}]))
结果是返回了一个数组:
这种方式不考虑兼容性,且去不掉重复的function和{}
关于Array.from()的扩展
Array.from(arrayLike[,mapFn[,thisArg]])
arrayLike:伪数组和可迭代对象
mapFn:每个元素会执行这个回调方法
thisArg:执行回调函数时this的指向。
constlist4=Array.from('name',arg=>arg+12) console.log(list4)//['n12','a12','m12','e12']
伪数组对象(拥有一个length属性和若干索引属性的任意对象,如string)
可迭代对象(可以获取对象中的元素,如Map和Set等)
二、set的另一种写法
constlist20=[5,3,5,5,6,37,22,22] console.log([...newSet(list20)])
其实跟第一种差不多
三、嵌套的for循环
constlist5=[null,null,undefined,undefined,{},{},functionq(){},functionq(){},34,2,1,2] for(leti=0;i这种方式用了splice(index,num)的方法,返回的结果也没有把function和对象给去掉。我们能想到的最简单的方式就是这种去重方式。
四、indexOf方式
constlist6=[null,null,undefined,undefined,NaN,NaN,false,'false',functiona(){},functiona(){},{},{}] constlist7=[] for(letk=0;k关于indexOf
Array构造函数和String构造函数的原型上都有这个方法
MDN上对他们的解释分别是:
**indexOf()**方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
arr.indexOf(searchElement[,fromIndex])**indexOf()**方法返回调用它的String对象中第一次出现的指定值的索引,从fromIndex处进行搜索。如果未找到该值,则返回-1。
str.indexOf(searchValue[,fromIndex])这么一看就知道他俩用法一样。
五、sort
先看看关于sort的解释:
**sort()**方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的
由于它取决于具体实现,因此无法保证排序的时间和空间复杂性。所以这种方式,在数组长的时候可能保证不了性能。用它去重的思路是什么呢?先用sort排序,然后前一个跟后一个比较,这样相同的值永远都是邻关系。
constlist8=[null,null,undefined,undefined,NaN,NaN,false,'false',functiona(){},functiona(){},{},{}] constlist9=list8.sort() constlist10=[list9[0]] for(leti=1;i这一看就很容易理解。
六、includes
constlist11=[null,null,undefined,undefined,NaN,NaN,false,'false',functiona(){},functiona(){},{},{}] constlist12=[] for(leti=0;i此结果没有把function和{}去重,其他的都去重了。
includes也是Array构造函数和String构造函数上都有的方法。
七、filter和indexOf
//数组去重方式6-filter和indexOf constlist13=[1,2,3,3,5] constlist14=list13.filter((item,index,arr)=>{ //也就是在遍历这个数组list13的时候,每次拿当前的元素跟此数组中这个元素第一次出现的位置相比,如果位置是一致的,就返回当前元素 returnlist13.indexOf(item,0)===index })八、递归
constlist15=[1,2,3,4,5,7,6,4,3] constlist16=list15 constlen=list16.length list16.sort(function(a,b){returna-b})//先排序 functionloop(index){ if(index>=1){ if(list16[index]===list16[index-1]){ list16.splice(index,1) } loop(index-1) } } loop(len-1)关于sort排序
在排序的时候我们可能忽略了一个问题,可能得到的并不是我们想要的结果,比如下面的例子:
constlist17=[22,1,2,15,3,4,3,1,11] console.log(list17.sort())//[1,1,11,15,2,22,3,3,4]看看得到的结果,根本就不是按照从小到大排的。这是因为:默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的。
所以要另找一种排序的方法,就是给sort传入一个函数。arr.sort([compareFunction])
参数:
- compareFunction:可传可不传,传的话用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的Unicode位点进行排序。
- compareFunction的参数1-firstEl:用于比较的第一个元素
- compareFunction的参数2-secondEl:用于比较的第二个元素
- 如果compareFunction(a,b)小于0,那么a会被排列到b之前;
- 如果compareFunction(a,b)等于0,a和b的相对位置不变。备注:ECMAScript标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如Mozilla在2003年之前的版本);
- 如果compareFunction(a,b)大于0,b会被排列到a之前。
- compareFunction(a,b)必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。
返回值:
返回的是已经原地排序的数组。
九、用Map数据结构排序
constlist18=[2,3,33,2,5,1,3] constmap1=newMap() for(leti=0;i这个比较好理解,就不多说了。
总结
到此这篇关于关于JavaScript数组去重的一些理解的文章就介绍到这了,更多相关JavaScript数组去重内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。