利⽤JS⼗分钟判断数组中存在元素的多种⽅式
前⾔
在前端开发中,经常会遇到要判断数组中是否存在某个元素。其实判断的⽅式有很多种,我们⼀个⼀个来了解下。
我们先来定义⼀个数组:
const arr = [
13,
false,
'abcd',
undefined,
13,
null,
NaN,
[1, 2],
{ a: 123 },
() => w(),
new Date('2021/03/04'),
new RegExp('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(() => w()); // -1
arr.indexOf(new Date('2021/03/04')); // -1
arr.indexOf(new RegExp('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(() => w()); // false
arr.includes(new Date('2021/03/04')); // false
arr.includes(new RegExp('abc', 'ig')); // false
arr.includes(Symbol('sym')); // false
结局很惨,这⼏种元素在数组中都没有检索到。可是实际上在数组中都是真实存在的。
这是因为 indexOf 和 includes 都是采⽤严格相等的⽅式(===)来判定的。
NaN === NaN; // false, 两个NaN永远也不会相等
[1, 2] === [1, 2]; // false, 每个声明出来的数组都有单独的存储地址
{a: 123} === {a: 123}; // false, 同数组
new Date('2021/03/04')===new Date('2021/03/04'); // false, 看着⽇期是相同的,但是⽤new出来的对象进⾏⽐较的,肯定是不相等的
Symbol('sym')===Symbol('sym'); // Symbol类型的出现就是为了避免冲突创造出来的类型,括号⾥的属性仅是为了⽅便描述⽽已
针对这些⽆法被检索的类型,我们就需要⾃⼰写函数来判断特殊的类型了。
3. find 和 findIndex
find()和 findIndex()允许我们通过回调函数,来⾃定义判断的⽅式。
3.1 find ⽅法
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) => typeof item === 'number' && isNaN(item)); // NaN
// array和object类型进⾏⽐较时,情况很复杂,因为每个元素的类型都⽆法确定
// 如果确定都是基本类型,如string, number, boolean, undefined, null等,可以将其转为字符串再⽐较
// 转字符串的⽅式也很多,如JSON.stringify(arr), String(), arr.split('|')等
// 复杂点的,只能⼀项⼀项⽐较,或者使⽤递归
arr.find((item) => String() === [1, 2].toString()); // [1, 2]
arr.find((item) => JSON.stringify(item) === JSON.stringify({ a: 123 })); // {a: 123}
arr.find((item) => {
if (typeof item === 'function') {
String() === (() => w()).toString();
}
return false;
}); // () => w()
arr.find((item) => {
if (item instanceof Date) {
String() === new Date('2021/03/04').toString();
}
return false;
}); // Thu Mar 04 2021 00:00:00 GMT+0800
arr.find((item) => {
if (item instanceof RegExp) {
String() === new RegExp('abc', 'ig').toString();
}
return false;
}); // /abc/gi
// Symbol确实没法⽐较,只能⽐较描述是否⼀样
arr.find((item) => {
if (typeof item === 'symbol') {
String() === Symbol('sym').toString();
}
return false;
}); // Symbol(sym)
上⾯的判断代码在后⾯的⽅法也将会使⽤到。
3.2 两个元素进⾏⽐较
我们在上⾯对⽐了多种类型元素的⽐较,稍微来总结下。
先来定义⼀个函数:
const compare = (x, y) => {};
3.2.1 基本类型
对于元素是 string, number, boolean, undefined, null 等基本类型的,可以直接进⾏⽐较:const compare = (x, y) => {
return x === y;
};
3.2.2 NaN 数据
NaN ⽤ typeof 来判断是 number 类型,但 NaN 不与任何数字相等,包括它⾃⼰。
const compare = (x, y) => {
if (typeof x === 'number' && isNaN(x) && typeof y === 'number' && isNaN(y)) {
return true;
}
return x === y;
};
3.2.3 Function 与 Date 与 RegExp
这些类型的,可以将变量转为字符串进⾏⽐较:
const compare = (x, y) => {
if (typeof x === 'number' && isNaN(x) && typeof y === 'number' && isNaN(y)) {
return true;
}
if (
(typeof x === 'function' && typeof y === 'function') ||
(x instanceof Date && y instanceof Date) ||
(x instanceof RegExp && y instanceof RegExp) ||
(x instanceof String && y instanceof String) ||
(x instanceof Number && y instanceof Number)
)
{
String() === y.toString();
}
return x === y;
};
对于 object 类型和 array 的,我们可以将每⼀项拆开,然后利⽤上⾯的⽅式再挨个⼉⽐较。
3.3 findIndex ⽅法
如果还要判断数组中是否存在 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) => typeof item === 'number' && isNaN(item)); // true
arr.some((item) => item === 3); // false, 不存在数字3
typeof arrayarr.some((item) => {
if (item instanceof Date) {
String() === new Date('2021/03/04').toString();
}
return false;
}); // true
5. filter
filter() ⽅法创建⼀个新数组, 其包含通过所提供函数实现的测试的所有元素。
⽆论到⼏个元素或者没有元素,filter()⽅法都是会返回⼀个数组,数组中的数据就是我们想要的元素。
arr.filter((item) => item === false); // 1
arr.filter((item) => item === undefined); // 1
arr.filter((item) => typeof item === 'number' && isNaN(item)); // 1
arr.filter((item) => item === 13); // 2
arr.filter((item) => item === 3); // 0
arr.filter((item) => {
if (item instanceof Date) {
String() === new Date('2021/03/04').toString();
}
return false;
}); // 1
因此我们可以通过该数组的长度,来判断原数组是否包含我们想要的元素。
略略
6. 总结
查数组中元素的⽅式有很多,我们可以数组中元素的格式,来选择更合适的⽅式。如果都是⼀些基本类型,建议优先选择使⽤includes()⽅法;如果格式⽐较复杂的,建议选择使⽤some()⽅法。这两个⽅法都是直接返回 boolean 类型,⽆需更多的转换即可直接使⽤⽅法的结果。
到此这篇关于利⽤JS⼗分钟判断数组中存在元素的多种⽅式的⽂章就介绍到这了,更多相关JS判断数组存在元素内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。