JS判断数组是否包含某元素实现方法汇总


Posted in Javascript onJune 24, 2020

我在学习ES6数组拓展时,发现了新增了不少了有趣的数组方法,突然想好工作中判断数组是否包含某个元素是非常常见的操作,那么这篇文章顺便做个整理。

1.for循环结合break

可能很多人第一会想到for循环,毕竟for是最为保险和熟悉的操作:

let arr = [1, 2, undefined, '听风是风', 'echo'],
  i = 0;
const LENGTH = arr.length;

//初始化result状态,只要能找到匹配的则修改为true
let result = false;
for (; i < LENGTH; i++) {
  if (arr[i] === '听风是风') {
    result = true;
    break;
  };
};
if (result) {
  //do something...
};

使用for的好处是,能结合break在找到满足条件的情况下,立刻跳出循环,如果第一个元素就符合条件,那后续循环步骤都可以优化直接跳过了。

使用for的缺点是,查找不够直观,我们在for循环中无法直接return查询结果,当然你可以将for循环写在一个函数中,但你还是需要额外定义个result变量。

其次,对于数组操作,我们虽然能使用for循环解决很多问题,但我们不能把目光永远第一个投向for,除了for呢?试着将目光投向更多数组高阶函数,思考更多可能是非常必要的。

说到for你肯定会本能想到forEach,虽然forEach能使用回调函数,但依旧无法在回调函数中使用return,外加上无法直接使用break,这里就不做介绍了。

最后,for循环与forEach对于查找NaN不那么实用,毕竟NaN是唯一一个不等于自己的存在,当然也能实现又能判断NaN还能判断其它非NaN对象,只是比较麻烦了。

2.Arr.indexOf()方法

let arr = [1, 2, undefined, '听风是风', 'echo'];

//利用indexOf查找下标的特性
let result = arr.indexOf('听风是风');//3
if (result>-1) {
  //do something...
};

indexOf方法会从头到尾的检索数组,如果找到了第一个符合条件的元素则返回该元素的下标,如果没找到则返回-1,所以只要能找到最小下标也应该是0,这才有了if(result>-1)的写法。

相对for循环来说,indexOf写法上简洁了不少,但相比for循环能使用break,indexOf即便找到了想要的元素,它还是不会停下检索的脚步,这点就不太优化了。

其次,语义化不太友好,我们是希望判断一个数组有没有某个元素,结果我们到底是拿了下标来做判断,当然,对于NaN查找也不那么友好。

[NaN].indexOf(NaN);//-1

3.find()与findIndex()方法

let arr = [1, 2, undefined, '听风是风', 'echo'];

//利用indexOf查找下标的特性
let result = arr.find(ele => ele === '听风是风')//听风之风
if (result) {
  //do something...
};

find方法是比较推荐的做法,find方法会找到第一个符合条件的数组元素,并返回它,如果没找到则返回undefined。

需要注意的是,只要find找到符合条件的对象后不会继续遍历,可以说自带了break操作,加上箭头函数简化回调,整体代码非常直观。

let arr = [1, 2, undefined, '听风是风', 'echo'];

//利用indexOf查找下标的特性
let result = arr.findIndex(ele => ele === '听风是风')//3
if (result>-1) {
  //do something...
};

findIndex方法与find方法非常类似,只是它返回的不是符合条件的对象,而是该对象的下标,找到后同样会跳出循环,如果没找到则返回-1,这一点与indexOf有点类似。

比较理想的是,find方法还能结合Object.is()方法判断NaN,当然也能判断其它对象,是不是非常的奈斯?

[NaN].find(ele => Object.is(NaN, ele)); //NaN
[1].find(ele => Object.is(1, ele)); //1
[NaN].findIndex(ele => Object.is(NaN, ele)); //0
[1].findIndex(ele => Object.is(1, ele)); //0

写法简洁,自带break,还能判断NaN,这两个方法都比较推荐。

4.some()方法

let arr = [1, 2, undefined, '听风是风', 'echo'];

//利用indexOf查找下标的特性
let result = arr.some(ele => ele === '听风是风') //true
if (result) {
  //do something...
};

some方法同样用于检测是否有满足条件的元素,如果有,则不继续检索后面的元素,直接返回true,如果都不符合,则返回一个false。

用法与find相似,只是find是返回满足条件的元素,some返回的是一个Boolean值,从语义化来说,是否包含返回布尔值更贴切。

当然,some方法同样能结合Object.is()方法检测NaN。some也是较为推荐的方法

[NaN].some(ele => Object.is(NaN, ele));

5.includes()方法

ES6新增的数组方法,用于检测数组是否包含某个元素,如果包含返回true,否则返回false,比较厉害的是,能直接检测NaN:

[1, 3, 'echo'].includes('echo'); //true
[NaN, 3, 'echo'].includes(NaN); //true
[1, 3, 'echo'].includes('听风是风'); //false

优点就不用说了,最简单的做法没有之一,不用回调,不用复杂的写法,一个方法直接搞定。

缺点是低版本浏览器支持不是很友好,当然能用我们还是用,不能用我们就自己封装:

let hasEle = (() =>
  Array.prototype.includes ?
  (arr, val) => arr.includes(val) :
  (arr, val) => arr.some(ele => Object.is(val, ele))
)();

hasEle([1, 2, NaN], 1) //true
hasEle([1, 2, NaN], NaN) //true
hasEle([1, 2, NaN], '听风是风') //false

希望到这里,在以后查找某数组是否包含某元素时,你又多了几种新的花样。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery.get、jQuery.getJSON、jQuery.post无法返回JSON问题的解决方法
Jul 28 Javascript
使用javascript实现有效时间的控制,并显示将要过期的时间
Jan 02 Javascript
火狐下input焦点无法重复获取问题的解决方法
Jun 16 Javascript
使用JavaScript为Kindeditor自定义按钮增加Audio标签
Mar 18 Javascript
JavaScript中输出信息的方法(信息确认框-提示输入框-文档流输出)
Jun 12 Javascript
AJAX和jQuery动态加载数据的实现方法
Dec 05 Javascript
微信小程序 生命周期和页面的生命周期详细介绍
Jan 19 Javascript
VUE元素的隐藏和显示(v-show指令)
Jun 23 Javascript
node.js之基础加密算法模块crypto详解
Sep 11 Javascript
element上传组件循环引用及简单时间倒计时的实现
Oct 01 Javascript
vue+webpack 更换主题N种方案优劣分析
Oct 28 Javascript
Ajax常用封装库——Axios的使用
May 08 Javascript
JS script脚本中async和defer区别详解
Jun 24 #Javascript
javascript实现前端分页效果
Jun 24 #Javascript
JS实现多选框的操作
Jun 24 #Javascript
微信小程序实现发微博功能的示例代码
Jun 24 #Javascript
JavaScript实现答题评分功能页面
Jun 24 #Javascript
JS实现电脑虚拟键盘打字测试
Jun 24 #Javascript
JS实现简单打字测试
Jun 24 #Javascript
You might like
php中的实现trim函数代码
2007/03/19 PHP
PHP企业级应用之常见缓存技术篇
2011/01/27 PHP
php sybase_fetch_array使用方法
2014/04/15 PHP
PHP使用glob函数遍历目录或文件夹的方法
2014/12/16 PHP
php获取文件名称和扩展名的方法
2017/02/07 PHP
js对数字的格式化使用说明
2011/01/12 Javascript
myeclipse安装jQuery插件的方法
2011/03/29 Javascript
改变文件域的样式实现思路同时兼容ie、firefox
2013/10/23 Javascript
JavaScript验证图片类型(扩展名)的函数分享
2014/05/05 Javascript
jQuery学习笔记之toArray()
2014/06/09 Javascript
如何编写高质量JS代码(续)
2015/02/25 Javascript
js实现a标签超链接提交form表单的方法
2015/06/24 Javascript
js查看一个函数的执行时间实例代码
2015/09/12 Javascript
详解AngularJS中的filter过滤器用法
2016/01/04 Javascript
基于Bootstrap实现图片轮播效果
2016/05/22 Javascript
bootstrap导航栏、下拉菜单、表单的简单应用实例解析
2017/01/06 Javascript
javascript匿名函数中的'return function()'作用
2018/10/15 Javascript
Vue递归组件+Vuex开发树形组件Tree--递归组件的简单实现
2019/04/01 Javascript
利用JavaScript将Excel转换为JSON示例代码
2019/06/14 Javascript
vue3 源码解读之 time slicing的使用方法
2019/10/31 Javascript
[00:52]玛尔斯技能全介绍
2019/03/06 DOTA
pytyon 带有重复的全排列
2013/08/13 Python
Python常用时间操作总结【取得当前时间、时间函数、应用等】
2017/05/11 Python
Python Dataframe 指定多列去重、求差集的方法
2018/07/10 Python
利用Python实现kNN算法的代码
2019/08/16 Python
对Django中内置的User模型实例详解
2019/08/16 Python
python 实现将Numpy数组保存为图像
2020/01/09 Python
Python3实现个位数字和十位数字对调, 其乘积不变
2020/05/03 Python
pycharm 配置svn的图文教程(手把手教你)
2021/01/15 Python
BCBG官网:BCBGMAXAZRIA
2017/12/29 全球购物
校庆筹备方案
2014/03/30 职场文书
工伤事故赔偿协议书
2014/04/15 职场文书
运动会班级口号
2014/06/09 职场文书
解除劳动合同协议书范本
2014/09/13 职场文书
MySQL 隔离数据列和前缀索引的使用总结
2021/05/14 MySQL
错误码NET::ERR_CERT_DATE_INVALID证书已过期解决方法?
2022/07/07 数码科技