数组遍历(for,forin,forof,forEach,map,filter,some,every,reduce)

2024-03-09 19:58

本文主要是介绍数组遍历(for,forin,forof,forEach,map,filter,some,every,reduce),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 数组遍历方法总结
    • for 循环
    • for...in 循环
    • for...of 循环
    • forEach 循环
    • map 循环
    • filter 循环
    • some 循环
    • every 循环
    • reduce 循环

数组遍历方法总结

这里记录一下,目前常用的针对数组的一些循环操作,以便以后随时翻阅。

  • 所有循环讲解主要部分均由代码展示,更简明明了。

for 循环

for 循环没啥说的,不过要记得:针对for循环,循环条件总比循环体要多执行一次。不过这个无伤大雅,一般我们都会忽略,下面看代码:

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]for(let i = 0; i < arr.length; i++) {let value = arr[i];console.log(value);
}# 输出结果:
# 1 2 3 4 5 6 7 8 9

for…in 循环

注意:for…in循环非常不建议用在数组上,for…in是为遍历对象属性而构建的,当然数组也可以用。

for...in循环在使用过程中要小心一点,可能会出现问题,这个下面会说到。先看 for…in 的使用:

const arr: any = [1, 2, 3, 4, 5, 6, 7, 8, 9];for(const key in arr) {console.log(key);
}# 输出结果:
# "0" "1" "2" "3" "4" "5" "6" "7" "8"

for…in 循环可以拿到数组的 key 值。针对上面的arr数组,拿到的也是key值,这个大家可以通过console.dir(arr) 来验证。

for…in使用时的bug:

这个bug的出现也具有一定的特殊性,就是我们对数组进行扩展时,使用forin循环,比如这样:

const arr: any = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// 给数组增加一个name属性
arr.name = '李明';for(const key in arr) {console.log(arr[key]);
}
# 输出结果
# 1 2 3 4 5 6 7 8 9 "李明"for(let i = 0; i < arr.length; i++) {console.log(arr[i])
}
# 输出结果
# 1 2 3 4 5 6 7 8 9

可以看到 forin 循环比着for循环要多输出了一个 ”李明“ ,为啥会这样呢?首先我们要知道一点:

  • for…in语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性 。
  • 很不巧,我们这样给arr增加的name属性是可枚举的,forin甚至可以遍历到你给Array.prototype增加的属性与方法遍历出来。

所以这样就会导致很多意外的结果和错误。

再者,for循环为啥就不会出错呢?

  • for 循环 ,循环的是次数,for循环不关注属性。

当然我们写代码的时候 尽量要保证数组中数据类型的唯一性,比如利用Typescript:

const arr:number = [1,2,3]

arr.name = 4;

如果强行编译,还是会加上的,但是Typescript会报给我们一个错误:Property 'name' does not exist on type 'number'.

总而言之,不建议使用forin遍历数组。

for…of 循环

for…of语句在 可迭代对象(包括 ArrayMapSetStringTypedArray,arguments对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句 。

for of循环是ES6的新增方法,针对for in循环的bug,for of循环就不会有问题:

const arr:any = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.name = 12;for(const item of arr) {console.log(item)
}# 输出结果:
# 1 2 3 4 5 6 7 8 9

使用for of 循环遍历数组,其结果就是打印出数组中的每一个值,所以可以放心使用。

附加:

  • 如果使用for…of 循环时也想得到数组的下标或者是key,可以利用arr.keys()

    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];for (let key of arr.keys()) {console.log(key)
    }# 输出结果:
    # 0 1 2 3 4 5 6 7 8
    
  • 如果使用for…of循环,既想得到key 也想得到 value ,可以利用arr.entries():

    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];for (let [key, val] of arr.entries()) {console.log(key, val)
    }# 输出结果:
    # 0,  1 
    # 1,  2 
    # 2,  3 
    # 3,  4 
    # 4,  5 
    # 5,  6 
    # 6,  7 
    # 7,  8 
    # 8,  9 
    

forEach 循环

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];arr.forEach((item, index, arr) => {console.log(item)
});# 输出结果:
# 1 2 3 4 5 6 7 8 9

注意:

  • forEach 循环对于空数组是不会执行回调函数的。
  • forEach 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。
  • forEach 循环本身不支持 continue 和 break语句的
    • 如果想实现continue效果,可以使用 return。
    • 如果要实现break效果,建议使用 every 和 some 循环。(这个后面会讲到)

map 循环

map循环返回一个经过调用函数处理后的新的数组

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];const res = arr.map((item,index,arr)=>{return item + 1
})
console.log(res)# 输出结果:
# [2, 3, 4, 5, 6, 7, 8, 9, 10] 

注意:

  • map 循环不会对空数组进行检测 。

  • map 循环必须 return 。

  • map 循环不会修改原数组。

  • map 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。

  • map 循环会针对每一项都进行循环,如果跳过则会返回 undefined,例如:

    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];const res = arr.map(item=>{if(item > 3) {return item;}
    })
    console.log(res)# 输出结果:
    # [undefined, undefined, undefined, 4, 5, 6, 7, 8, 9] 
    

filter 循环

filter() 循环返回一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];const res = arr.filter((item,index,arr)=>{return item > 3;
});
console.log(res)# 输出结果:
# [4, 5, 6, 7, 8, 9] 

注意:

  • filter 循环不会对空数组进行检测。
  • filter 循环不会改变原数组。
  • filter 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。

some 循环

some 循环查找数组中任意符合条件的元素并返回boolean值,当数组中有任意元素符合条件就返回 true 否则返回 fasle

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];const res = arr.some((item,index,arr)=>{return item > 3
})
console.log(res)# 输出结果:
# true

注意:

  • some 循环会依次执行数组的每一个元素。
  • 如果有一个元素满足条件,则返回 true,且剩余的元素不会在执行检测 即 循环结束。
  • some 循环不会对空数组进行检测
  • some 循环不会改变原数组
  • some 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。

every 循环

every 循环查找数组中所有符合条件的元素并返回boolean值,只有当数组中有所有元素都符合条件才返回 true 否则返回 fasle

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];const res = arr.every((item,index,arr)=>{return item > 3
})
console.log(res);# 输出结果:
# false

注意:

  • every 循环会检测数组的每一个元素
  • 如果有一个元素不满足条件,则返回false,且剩余元素不在检测 即 循环结束。
  • every 循环不会对空数组进行检测
  • every 循环不会改变原数组。
  • every 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。

reduce 循环

reduce() 循环接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];const res = arr.reduce((total,item,index,arr)=>{return total + item;
}, 0)
console.log(res);# 输出结果:
# 45

注意:

  • reduce 循环对于空数组是不会执行回调函数的。

  • reduce 循环接受一个回调函数,和一个初始值。

    • 回调函数接受四个参数:[第一参数]为数组中的每一项累加和,[第二参数]为数组的每一项,[第三个参数]为数组的下标,[第四个参数]为你要遍历的数组本身。第三和第四参数都是可选的。

    • 初始值,即为指定第一次循环时,累加参数[total] 的值。

      • 例如 demo 中,指定初始值为 0,则reduce循环的状态为:

        [total + item]
        0
        0 + 1 = 1
        1 + 2 = 3
        3 + 3 = 6
        ...
        36 + 9 = 45
        
  • reduce 可以作为一个高阶函数,用于函数的 compose。

  • 当然reduce 的作用也不单单只作为一个累加器来用,我们还可以利用reduce的特性做其他的用途,比如数组的去重


以上就是我记录的 数组的遍历方法了 。 完结·撒花

这篇关于数组遍历(for,forin,forof,forEach,map,filter,some,every,reduce)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/791785

相关文章

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

Collection List Set Map的区别和联系

Collection List Set Map的区别和联系 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

计算数组的斜率,偏移,R2

模拟Excel中的R2的计算。         public bool fnCheckRear_R2(List<double[]> lRear, int iMinRear, int iMaxRear, ref double dR2)         {             bool bResult = true;             int n = 0;             dou

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };

PHP实现二叉树遍历(非递归方式,栈模拟实现)

二叉树定义是这样的:一棵非空的二叉树由根结点及左、右子树这三个基本部分组成,根据节点的访问位置不同有三种遍历方式: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderT

PHP7扩展开发之数组处理

前言 这次,我们将演示如何在PHP扩展中如何对数组进行处理。要实现的PHP代码如下: <?phpfunction array_concat ($arr, $prefix) {foreach($arr as $key => $val) {if (isset($prefix[$key]) && is_string($val) && is_string($prefix[$key])) {$arr[