利用JS十分钟判断数组中存在元素的多种方式
前言
在前端开发中,经常会遇到要判断数组中是否存在某个元素。其实判断的方式有很多种,我们一个一个来了解下。
我们先来定义一个数组:
constarr=[ 13, false, 'abcd', undefined, 13, null, NaN, [1,2], {a:123}, ()=>Date.now(), newDate('2021/03/04'), newRegExp('abc','ig'), Symbol('sym'), ];
在这个数组中,我们包含了好几种类型:number,boolean,string,undefined,null,array,object,Date,Symbol等。其中数字13出现了2次。
有备而来
1.indexOf
我们最熟悉的就是indexOf了,毕竟他出现的早,兼容性也好,使用起来也很方便。
如果存在该元素,则返回第一次出现的索引值;若整个数组不存在该元素,则返回-1。
1.1使用方式
只要判断返回的数据是不是-1,就能知道数组中是否包含该元素。
arr.indexOf(13)>=0;//true,indexOf返回0 arr.indexOf(2)>=0;//false,indexOf返回-1
与indexOf对应的是lastIndexOf,从最后往前查找元素,若存在该元素,则返回在数组中的最后一个的索引;若不存在该元素,则返回-1。
arr.lastIndexOf(13)>=0;//true,lastIndexOf返回4,最后一次出现的索引
两个方法在判断变量是否存在时,调用方式是一样的。
1.2第2个可选参数
indexOf和lastIndexOf还有第2个可选参数fromIndex,用来表示从哪个索引开始进行搜索。
在indexOf中,若fromIndex超过数组的长度,则直接返回-1,若为负数,则从最后往前数几个索引(arr.length-Math.abs(fromIndex)),然后开始往后搜索。
在lastIndexOf中,若fromIndex达到或超过数组的长度,则搜索整个数组;若为负数,则从最后往前数几个索引(arr.length-Math.abs(fromIndex)),然后开始往前搜索,若负数的绝对值超过了数组的长度,则直接返回-1。
arr.indexOf(13,2);//4,从索引值2开始往后查找,首先找到的13的索引值为4 arr.indexOf(13,-10);//4,从索引值1(11-10)开始往后检索 arr.lastIndexOf(13,2);//0,从索引值2往前开始搜索 arr.lastIndexOf(13,-2);//4,从索引值9(11-2)开始往前搜索
而且indexOf和lastIndexOf中采用的是严格相等的方式(===)来判断的。
arr.indexOf(null);//5,在null的前面有几个假值false和undefined,也能准确找到null的索引值
瑟瑟发抖
2.includes
indexOf主要是为了查找元素所在的索引值,只是我们可以用返回的索引值来间接判断数组中是否存在该元素。
而在ES7(ES2016)中添加的includes方法,就是专门用来判断元素是否存在的。返回值为true或者false,true表示存在,false表示不存在,简单明了。
arr.includes(13);//true arr.includes('abc');//false arr.includes(false);//true,存在false元素
同时,includes方法中也存在第2个可选参数fromIndex,fromIndex的用法与indexOf中的一样。若fromIndex超过数组的长度,则直接返回-1,若为负数,则从最后往前数几个索引(arr.length-Math.abs(fromIndex)),然后开始往后搜索。
arr.includes(13,5);//false,从索引值5开始往后检索,没检索到
到目前为止,后面的几种类型,例如Array,Object,Date和Symbol,我们都没判断呢。我们现在来判断下后面的几个元素:
//使用indexOf判断 arr.indexOf(NaN);//-1 arr.indexOf([1,2]);//-1 arr.indexOf({a:123});//-1 arr.indexOf(()=>Date.now());//-1 arr.indexOf(newDate('2021/03/04'));//-1 arr.indexOf(newRegExp('abc','ig'));//-1 arr.indexOf(Symbol('sym'));//-1 //使用includes判断 arr.includes(NaN);//false arr.includes([1,2]);//false arr.includes({a:123});//false arr.includes(()=>Date.now());//false arr.includes(newDate('2021/03/04'));//false arr.includes(newRegExp('abc','ig'));//false arr.includes(Symbol('sym'));//false
结局很惨,这几种元素在数组中都没有检索到。可是实际上在数组中都是真实存在的。
这是因为indexOf和includes都是采用严格相等的方式(===)来判定的。
NaN===NaN;//false,两个NaN永远也不会相等 [1,2]===[1,2];//false,每个声明出来的数组都有单独的存储地址 {a:123}==={a:123};//false,同数组 newDate('2021/03/04')===newDate('2021/03/04');//false,看着日期是相同的,但是用new出来的对象进行比较的,肯定是不相等的 Symbol('sym')===Symbol('sym');//Symbol类型的出现就是为了避免冲突创造出来的类型,括号里的属性仅是为了方便描述而已
针对这些无法被检索的类型,我们就需要自己写函数来判断特殊的类型了。
3.find和findIndex
find()和findIndex()允许我们通过回调函数,来自定义判断的方式。
3.1find方法
find()方法返回数组中满足提供的测试函数的第一个元素的值。否则返回undefined。
find()方法无法检测数组中的undefined元素。
因为不存在和存在undefined元素,find()方法都会返回undefined。这里我们就要考虑其他方式了,稍后再讲。
arr.find((item)=>item===13);//13,找到了元素13 arr.find((item)=>item===3);//undefined,没找到元素3 arr.find((item)=>item===undefined);//undefined,也不知道是找到了还是没找到
对于上面稍微复杂点的类型,我们就需要特殊的判断了:
arr.find((item)=>typeofitem==='number'&&isNaN(item));//NaN //array和object类型进行比较时,情况很复杂,因为每个元素的类型都无法确定 //如果确定都是基本类型,如string,number,boolean,undefined,null等,可以将其转为字符串再比较 //转字符串的方式也很多,如JSON.stringify(arr),arr.toString(),arr.split('|')等 //复杂点的,只能一项一项比较,或者使用递归 arr.find((item)=>item.toString()===[1,2].toString());//[1,2] arr.find((item)=>JSON.stringify(item)===JSON.stringify({a:123}));//{a:123} arr.find((item)=>{ if(typeofitem==='function'){ returnitem.toString()===(()=>Date.now()).toString(); } returnfalse; });//()=>Date.now() arr.find((item)=>{ if(iteminstanceofDate){ returnitem.toString()===newDate('2021/03/04').toString(); } returnfalse; });//ThuMar04202100:00:00GMT+0800 arr.find((item)=>{ if(iteminstanceofRegExp){ returnitem.toString()===newRegExp('abc','ig').toString(); } returnfalse; });///abc/gi //Symbol确实没法比较,只能比较描述是否一样 arr.find((item)=>{ if(typeofitem==='symbol'){ returnitem.toString()===Symbol('sym').toString(); } returnfalse; });//Symbol(sym)
上面的判断代码在后面的方法也将会使用到。
3.2两个元素进行比较
我们在上面对比了多种类型元素的比较,稍微来总结下。
先来定义一个函数:
constcompare=(x,y)=>{};
3.2.1基本类型
对于元素是string,number,boolean,undefined,null等基本类型的,可以直接进行比较:
constcompare=(x,y)=>{ returnx===y; };
3.2.2NaN数据
NaN用typeof来判断是number类型,但NaN不与任何数字相等,包括它自己。
constcompare=(x,y)=>{ if(typeofx==='number'&&isNaN(x)&&typeofy==='number'&&isNaN(y)){ returntrue; } returnx===y; };
3.2.3Function与Date与RegExp
这些类型的,可以将变量转为字符串进行比较:
constcompare=(x,y)=>{ if(typeofx==='number'&&isNaN(x)&&typeofy==='number'&&isNaN(y)){ returntrue; } if( (typeofx==='function'&&typeofy==='function')|| (xinstanceofDate&&yinstanceofDate)|| (xinstanceofRegExp&&yinstanceofRegExp)|| (xinstanceofString&&yinstanceofString)|| (xinstanceofNumber&&yinstanceofNumber) ){ returnx.toString()===y.toString(); } returnx===y; };
对于object类型和array的,我们可以将每一项拆开,然后利用上面的方式再挨个儿比较。
3.3findIndex方法
如果还要判断数组中是否存在undefined,我们可以使用findIndex()方法。
findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。
arr.findIndex((item)=>item===undefined);//3 arr.findIndex((item)=>item===3);//-1,没有找到数字3
其他数据格式的判断,与上面的find()一样。
稀客呀
4.some
some()方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。
注意:如果用一个空数组进行测试,在任何情况下它返回的都是false。
some()方法与find()方法的使用方式一样,只不过some()方法返回的是boolean类型的数据。
arr.some((item)=>item===false);//true arr.some((item)=>item===undefined);//true arr.some((item)=>typeofitem==='number'&&isNaN(item));//true arr.some((item)=>item===3);//false,不存在数字3 arr.some((item)=>{ if(iteminstanceofDate){ returnitem.toString()===newDate('2021/03/04').toString(); } returnfalse; });//true
5.filter
filter()方法创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
无论找到几个元素或者没有元素,filter()方法都是会返回一个数组,数组中的数据就是我们想要的元素。
arr.filter((item)=>item===false);//1 arr.filter((item)=>item===undefined);//1 arr.filter((item)=>typeofitem==='number'&&isNaN(item));//1 arr.filter((item)=>item===13);//2 arr.filter((item)=>item===3);//0 arr.filter((item)=>{ if(iteminstanceofDate){ returnitem.toString()===newDate('2021/03/04').toString(); } returnfalse; });//1
因此我们可以通过该数组的长度,来判断原数组是否包含我们想要的元素。
略略
6.总结
查找数组中元素的方式有很多,我们可以数组中元素的格式,来选择更合适的方式。如果都是一些基本类型,建议优先选择使用includes()方法;如果格式比较复杂的,建议选择使用some()方法。这两个方法都是直接返回boolean类型,无需更多的转换即可直接使用方法的结果。
到此这篇关于利用JS十分钟判断数组中存在元素的多种方式的文章就介绍到这了,更多相关JS判断数组存在元素内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。