zoukankan      html  css  js  c++  java
  • JS判断数组是否包含某元素

    我在学习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

    2.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,这两个方法都比较推荐。

    3.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));

    4.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

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

  • 相关阅读:
    sshpass连接主机以及执行命令
    elk集群配置并破解x-pack
    socket实现简单通信会话
    docker容器跨宿主机通信
    docker运行wordpress
    centos7 利用docker运行nginx项目
    docker容器基础命令
    docker镜像基础命令
    vue中使用延时加载
    less
  • 原文地址:https://www.cnblogs.com/echolun/p/10965123.html
Copyright © 2011-2022 走看看