javascript数组的遍历

作者: 邪恶的罐子 | 来源:发表于2017-03-15 12:57 被阅读123次

    这一节我们一起整理一下数组的遍历,目前来说遍历数组的方式非常多,首先我们来列举一下有哪些:

    • for
    • for-in
    • for-of
    • forEach
    • map
    • some
    • every
    • filter
    • find
    • findIndex
    • reduce
    • reduceRight
    • keys
    • entries

    有些我们之前就认识,有些也是我最近学到的
    按照惯例,我们需要先定义一个被测试的数组:

    let arr = Array.of(1, 'str', false, []);
    
    // 注意这句,我目的是让索引值为4的那一项为空值
    arr[5] = {};
    
    // 所以我们得到的数组结构为
    [1, 'str', false, [],  , {}]
    

    我们正式开始:


    for

    for (let i = 0, len = arr.length; i < len; i++) {
        console.log(i, arr[i])
    }
    

    打印的结果为:

    0 -> 1
    1 -> 'str'
    2 -> false
    3 -> []
    4 -> undefined
    5 -> Object {}
    

    根据结果我们分析为:

    1. 索引值i为Number类型
    2. 遍历过程中如果遇到空值,依然会执行,返回undefined

    for-in

    for (let i in arr) {
        console.log(i, arr[i])
    }
    

    打印的结果为:

    '0' -> 1
    '1' -> 'str'
    '2' -> false
    '3' -> []
    '5' -> Object {}
    

    大体上和for循环比较类似,但还是有所区别的

    1. 索引值i为String类型(这点我也不是很懂为什么...)
    2. 遍历过程中如果遇到空值,则会跳过

    for-of

    for (let i of arr) {
        console.log(i)
    }
    

    打印的结果为:

    1
    'str'
    false
    []
    undefined
    Object {}
    
    1. 与前两个不同的是,该循环的i是被遍历数组的键值
    2. 遍历过程中如果遇到空值,依然会执行,返回undefined

    forEach

    arr.forEach((value, index, arr) => {
        console.log(value)
    })
    

    打印的结果为:

    1
    'str'
    false
    []
    Object {}
    
    1. 首先,forEach无返回值,所以回调函数也不需要return
    2. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
    3. 遍历过程中如果遇到空值,跳过

    map

    let result = arr.map((value, index, arr) => {
        console.log(value)
        return value
    })
    

    打印的结果为:

    1
    'str'
    false
    []
    Object {}
    
    1. map函数会根据回调函数中return的值(为新数组的值)得到一个新的数组
    2. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
    3. 遍历过程中如果遇到空值,跳过

    所以如果需要根据原数组的值得到一个相关联的新数组时,比较适合使用map
    例:

    let newarr = [1, 2, 3].map(value => value * 2)
    

    以上代码可以得到这样一个数组:

    [2, 4, 6] // newarr
    

    some

    some用于检测数组中的某一项是否符合条件

    let result = arr.some((value, index, arr) => {
        return typeof value == 'string'
    })
    

    根据被测试的这个数组,我们得到的结果是:

    true // result
    

    因为索引值为1的那一项确实为String类型

    1. 返回Boolean类型的值
    2. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
    3. 回调函数需要返回true或者false
    4. 遍历过程中如果某个回调函数返回true时,停止遍历,result得到true
    5. 如果直到遍历结束所有回调函数均返回false,那么result便为false
    6. 遍历过程中如果遇到空值,跳过

    every

    every与some相反,用于检测数组中的每一项是均否符合条件

    let result = arr.every((value, index, arr) => {
        return typeof value == 'string'
    })
    

    很显然,根据被测试的这个数组,我们得到的结果是:

    false // result
    

    看懂some之后every其实也就明白是做什么的了

    1. 返回Boolean类型的值
    2. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
    3. 回调函数需要返回true或者false
    4. 遍历过程中如果某个回调函数返回false时,停止遍历,result得到false
    5. 如果直到遍历结束所有回调函数均返回true,那么result便为true
    6. 遍历过程中如果遇到空值,跳过

    filter

    let result = arr.filter((value, index, arr) => {
        return typeof value == 'object'
    })
    

    打印的结果为:

    [Array[0], Object {}] // result
    
    1. filter会根据回调函数中return的值(Boolean值)得到一个新的数组
    2. 回调函数需要返回一个Boolean值,为true时,filter的结果数组中将会得到该值,为false时跳过
    3. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
    4. 遍历过程中如果遇到空值,跳过

    说下filter与map的区别:

    • 第一点当然是回调函数返回值的不同,filter的回调函数返回布尔值,map的回调函数是将新数组所需要的值返回出来,所以filter只能选择要或者不要,而map可以给值做相应的调整,比如数组[1, 2, 3]我要得到一个新数组[2, 4, 6]时,使用map会很方便的做到。
    • 第二点是filter可以舍弃掉值,即比如数组[1, 2, 3]我们可以做到得到一个内容[2, 3]的数组,只要在回调函数中return value > 1即可,而map做不到,正常情况下被操作的数组与得到的新数组的length相等,不过length这里在有数组中有空值的情况下会不等,因为filter会跳过空值,所以本例子中被测试数组的length6,而filter即使回调函数全部返回true,得到的新数组的length也为5

    find

    find顾名思义是要找什么东西,所以不难想象find的返回值是被遍历数组中的某一项,我们来试试从测试数组中找String类型的值:

    let result = arr.find((value, index, arr) => {
        return typeof value == 'string'
    })
    

    打印的结果为:

    'str' // result
    

    有一点要注意的是,他只能从头开始找到最先找到的那个,并非全部找出来
    所以以下这种情况下只会找到1

    let res = [1, 2, 3, 4, 5].find(val => val < 9) // res -> 1
    
    1. find会根据回调函数中return的值(Boolean值)得到return true的那个键值
    2. 当回调函数返回true之后,停止遍历,所以只会得到一个结果
    3. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
    4. 遍历过程中如果遇到空值,依然会执行,返回undefined

    findIndex

    看完find之后,我相信findIndex也就明白了,用法是几乎一样

    let result = arr.findIndex((value, index, arr) => {
        return typeof value == 'string'
    })
    

    因为'str'的索引值为1,所以打印的结果为:

    1 // result
    
    1. findIndex会根据回调函数中return的值(Boolean值)得到return true的那个键值的索引值
    2. 当回调函数返回true之后,停止遍历,所以只会得到一个结果
    3. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
    4. 遍历过程中如果遇到空值,依然会执行,返回undefined

    reduce

    reduce比较有意思,我们先看测试代码再做分析:

    let arr2 = [1.2, 3.3, 5.4, 3.2, 5.3, 4.1, 4.9];
    let result = arr2.reduce((prev, next) => {
        let p = Math.abs(prev - 5), n = Math.abs(next - 5)
        return p < n ? prev : next
    })
    

    这段代码的意思是这样的:
    arr2中找到最接近5的那个值回调函数接收2个值
    第一次遍历时传递的是索引值为01的两个值,本例子中实为1.23.3,然后回调函数中实为返回了3.3这个值
    第二次遍历,注意,传递的值变成了前一次遍历return的值与下一个索引值相关的值,既3.3与索引值为25.4,然后我判断下来说5.4更接近5,所以返回了5之后的遍历以此类推,直到结束
    所以result最终结果为:

    4.9 // result
    

    还有个reduceRight方法我就不写了,我测试下来和reduce区别仅在于reduceRight是从数组最末位倒序执行


    keys

    数组的实例方法,返回一个数组的遍历器:

    for (let i of arr.keys()) {
        console.log(i)
    }
    

    打印结果为:

    0
    1
    2
    3
    4
    5
    
    1. 可以用for of取到数组的索引
    2. 遍历过程中如果遇到空值,会执行
    3. 和for循环表现一致

    entries

    同样也是数组的实例方法,返回一个数组的遍历器:

    for (let i of arr.entries()) {
        console.log(i)
    }
    

    打印结果为:

    [0, 1]
    [1, 'str']
    [2, false]
    [3, Array [0]]
    [4, undefined]
    [5, Object {}]
    
    1. 可以用for of取到数组的索引和键值
    2. 循环得到的结果是Array类型,[0]为索引,[1]为键值
    3. 遍历过程中如果遇到空值,会执行,键值为undefined

    当然你要是喜欢,可以用解构赋值的方式:

    for (let [index, value] of arr.entries()) {
        console.log(index, value)
    }
    

    关于数组的解构赋值这里就不多说了...


    有一点要提的是,关于空值的处理,实在是没什么规律可以找,有些处理方式是跳过,有些则是返回undefined,所以保险起见,还是尽量别在数组中出现空值的情况
    好了,以上学习资料仅供参考,如果有坑请以各大官方资料为准...

    相关文章

      网友评论

        本文标题:javascript数组的遍历

        本文链接:https://www.haomeiwen.com/subject/qswknttx.html