JS遍历数组的十五种方法

article/2025/9/10 8:37:06

一、循环遍历
for循环,也是最常见的。

可以使用临时变量,将长度缓存起来,避免重复获取数组长度,当数组较大时优化效果才会比较明显。

// arr 是要遍历的数组
// arr[i] 是遍历的数组的元素
// i 是数组的元素对应的下标(索引号)
for (var i = 0; i < arr.length; i++) {console.log(arr[i]);
}let arr = [1, 2, 3, 4];
for (let i = 0; i < arr.length; i++) {arr[i] = arr[i] + 1; // 直接通过索引修改原数组的值
}
console.log(arr); // [2,3,4,5]let list = [{sex: '男'},{sex: '女'},{sex: '男'}];
for (let i = 0; i < list.length; i++) {list[i].sex = '女';
}
console.log(list); // [{sex: '女'}, {sex: '女'}, {sex: '女'}]


二、for of遍历

// arr 遍历的数组
// item 遍历的数组的元素
for(var item of arr) {console.log(item);
}let arr = [1, 2, 3, 4];
for(var item of arr) {console.log(item);
}  // 1 2 3 4


三、for in遍历

// arr 遍历的数组
// item 遍历的数组的元素
for(var index in arr) {console.log(item);
}let arr = [1, 2, 3, 4];
for(var index in arr) {console.log(item);
} // 0 1 2 3

四、forEach()遍历


这种方法只是使处理需要循环的数组变得更加容易,因为你不必像通常那样写出笨重而长的for循环语句。

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数,没有返回值,原数组不变。

forEach() 对于空数组是不会执行回调函数的。

注意和map方法区分。

// arrObj 需要遍历的数组
// item 遍历出的每一个元素
// index 元素对应的下标
// self 数组本身
// 无返回值
arrObj.forEach(function(item,index,self) {console.log(item);
});let arr = [1, 2, 3, 4];
arr.forEach(item => {item = item * 2;
});
console.log(arr); // [1, 2, 3, 4]   原数组保持不变


五、map()映射遍历


map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值,并没有改变原来的数组。

map() 方法按照原始数组元素顺序依次处理元素。

注意:map() 不会对空数组进行检测。

// arrObj 需要遍历的数组
// item 遍历出的每一个元素
// index 元素对应的下标
// self 数组本身
// 有返回值
// newArr 新返回的数组
// 数组元素个数不变,但是按照一定的条件转换
arrObj.map(function(item,index,self) {return item*2;
});let arr = [1, 2, 3, 4];
let newArr = arr.map(item => {return item * 2;
});
console.log(arr); // [1, 2, 3, 4]   原数组保持不变
console.log(newArr); // [2, 4, 6, 8] 返回新数组

for 与 forEach、map的区别

  • 在固定长度或者长度不需要计算的时候for循环效率高于foreach和map,for循环中可以通过break终止。
  • 在不确定长度或者计算长度有损性能的时候用foreach和map比较方便

forEach、map的区别
相同点

  •         都是循环遍历数组中的每一项
  •         forEach和map方法里每次执行匿名函数都支持3个参数,参数分别是item(当前每一项),index(索引值),arr(原数组)
  • 匿名函数中的this都是指向window
  • 只能遍历数组
  • 都不会改变原数组

不同点:

  • map方法返回一个新的数组,数组中的元素为原始数组调用函数处理后的值
  • forEach方法不会返回新数组

性能:

  •         for > forEach > map
  •         for 循环当然是最简单的,因为它没有任何额外的函数调用栈和上下文
  •         forEach 其次,因为它其实比我们想象得要复杂一些。它不是普通的 for 循环的语法糖,还有诸多参数和上下文需要在执行的时候考虑进来,这里可能拖慢性能;
  •         map 最慢,因为它的返回值是一个等长的全新的数组,数组创建和赋值产生的性能开销很大。

六、filter()过滤遍历


将所有元素进行判断,将满足条件的元素作为一个新的数组返回, 原数组不变。

注意:filter() 不会对空数组进行检测。

// arrObj 需要遍历的数组
// item 遍历出的每一个元素
// index 元素对应的下标
// self 数组本身
// 有返回值,返回满足某个条件的元素构成的数组
// 数组元素个数可能改变,按照一定的条件返回
arrObj.filter(function(item,index,self) {return item < 3;
});let arr = [1, 2, 3, 4];
let newArr = arr.filter(item => {return item < 3;
});
console.log(arr); // [1, 2, 3, 4]   原数组保持不变
console.log(newArr); // [1, 2]   返回新数组


七、find()遍历


数组中的每个元素都调用一次函数执行。

当数组中的元素在测试条件时返回true,find()返回符合条件的元素,之后的值不会再执行函数;如果没有符合条件的元素则返回undefined,原数组不变。

注意::find() 对于空数组,函数是不会执行的。

let arr = [1, 2, 3, 4];
let newArr1 = arr.find(item => {return item > 2;
});
let newArr2 = arr.find(item => {return item > 5;
});
console.log(arr); // [1, 2, 3, 4]   原数组保持不变
console.log(newArr1); // 3  返回第一个符合条件的元素
console.log(newArr2); // undefined  没有符合条件的元素则返回undefined


八、findIndex()遍历


遍历数组,找到第一个符合条件的元素,并返回该元素;否则,返回-1。

不改变原数组。

let fruits= ['苹果', '梨子', '桃子', '西瓜', '哈密瓜'];
let vegetables= [{id: 1,name: '花椰菜'
},{id: 2,name: '青椒'
},{id: 3,name: '土豆'
},{id: 4,name: '西红柿'
}];// fruits 需要遍历的数组
// item 数组的元素
// index 元素对应的下标
// arr 数组本身
let findIndexFru = fruits.findIndex(function(item, index, arr){return index > 5;
});
console.log(findIndexFru); // -1let findIndexVeg = vegetables.findIndex(function(item, index, arr){// 返回 遍历子对象console.log(item.name);// // 返回 遍历索引值console.log(index);// 返回 所有子对象console.log(arr);return item.id> 2;
});
console.log(findIndexVeg);


九、indexOf()遍历


从前往后遍历数组,找到第一个符合条件的项,并返回该项。否则返回-1。

不改变原数组。

字符串也有此方法,功能类似。

let fruits= ['苹果', '梨子', '桃子', , '西瓜', '哈密瓜'];// fruits 需要遍历的数组
// item 需要搜索的值
// index 数组中的的索引值,可以为负数,代表相对数组末尾的偏移量
let indexOfFru = fruits.indexOf('桃子');
console.log(indexOfFru); // 2


十、lastIndexOf()遍历


从后往前遍历数组,找到第一个符合条件的项,并返回该项。否则返回-1。

不改变原数组。

字符串也有此方法,功能类似。

let fruits= ['苹果', '梨子', '桃子', '西瓜', '哈密瓜'];// fruits 需要遍历的数组
// item 需要搜索的值
// index 数组中的的索引值,可以为负数,代表相对数组末尾的偏移量
let lastIndexOfFru = fruits.lastIndexOf('西瓜');
console.log(lastIndexOfFru); // 3


十一、every()遍历


将所有元素进行判断,返回一个布尔值,原数组不变。

如果所有元素都满足判断条件,则返回true,否则为false。

注意:every() 不会对空数组进行检测。

// arrObj 需要遍历的数组
// item 遍历出的每一个元素
// index 元素对应的下标
// self 数组本身
// 有返回值,检测数组里的每一个值是否满足指定条件,如果有一个值不满足,返回false,剩余的值不再进行检测;如果所有的值都满足,则返回true
arrObj.every(function(item,index,self) {return item < 3;
});let arr = [1, 2, 3, 4];
let newArr1 = arr.every(item => {return item > 2;
});
let newArr2 = arr.every(item => {return item < 5;
});
console.log(arr); // [1, 2, 3, 4]   原数组保持不变
console.log(newArr1); // false
console.log(newArr2); // true


十二、some()遍历


将所有元素进行判断, 返回一个布尔值, 原数组不变。

如果存在元素满足判断条件,则返回true,若所有元素都不满足判断条件,则返回false。

判断条件注意和every方法区分。

// arrObj 需要遍历的数组
// item 遍历出的每一个元素
// index 元素对应的下标
// self 数组本身
// 有返回值,检测数组里的每一个值是否满足指定条件,如果有一个值不满足,返回false,剩余的值不再进行检测;如果所有的值都满足,则返回true
arrObj.every(function(item,index,self) {return item < 3;
});let arr = [1, 2, 3, 4];
let newArr1 = arr.every(item => {return item > 2;
});
let newArr2 = arr.every(item => {return item < 5;
});
console.log(arr); // [1, 2, 3, 4]   原数组保持不变
console.log(newArr1); // false
console.log(newArr2); // true

十三、reduce高阶函数(迭代(累加器))

// arrObj 需要遍历的数组
// item 遍历出的每一个元素
// index 元素对应的下标
// self 数组本身
// 有返回值,检测数组里的每一个值是否满足指定条件,如果有一个值不满足,返回false,剩余的值不再进行检测;如果所有的值都满足,则返回true
arrObj.every(function(item,index,self) {return item < 3;
});let arr = [1, 2, 3, 4];
let newArr1 = arr.every(item => {return item > 2;
});
let newArr2 = arr.every(item => {return item < 5;
});
console.log(arr); // [1, 2, 3, 4]   原数组保持不变
console.log(newArr1); // false
console.log(newArr2); // true

十四、reduceRight()遍历


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

第二个参数作为第一次调用的a的值。

let arrNum = [2, 4, 6, 8, 10];
// 累加
let sum = arrNum.reduceRight(function(x, y){return x + y;
});
console.log(sum); // 30// 累乘
let multiple = arrNum.reduceRight(function(x, y){return x * y;
});
console.log(multiple); // 3840// 求最大值
let bigger = arrNum.reduceRight(function(x, y){return x > y ? x : y;
});
console.log(bigger); // 10


十五、遍历器机制


截止到ES6,JavaScript 已经拥有了数组、对象、Map集合和Set集合这样四种数据结构。

为了统一和简化遍历这四种数据结构的操作,ES6引入了遍历器机制。

ES6 规定,可遍历的对象都具有Symbol.iterator 属性,这个属性指向一个函数,就是当前对象默认的遍历器生成函数。

这个遍历器生成函数大致的模样可以用ES5 语法模拟出来:这个函数返回一个next() 方法,每调用next() 方法,都会返回数据结构的当前成员的信息。

具体来说,就是返回一个包含value和done两个属性的对象。

其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。

在ES6 中,已经默认为绝大多数內建的数据结构提供了遍历器,不需要自己去创建。

// keys()方法:默认遍历器,其值为集合中的所有键名。
// values()方法:默认遍历器,其值为集合中的所有值。
// entries()方法:默认遍历器,其值为所有成员的键值对。
const arr = ["A", "B", "C"];
console.log([...arr.keys()]); // [0, 1, 2]
console.log([...arr.values()]); // ["A", "B", "C"]
console.log([...arr.entries()]); // [[0, "A"],[1, "B"],[2, "C"]]const set = new Set(arr);
console.log([...set.keys()]); // ["A", "B", "C"]
console.log([...set.values()]); // ["A", "B", "C"]
console.log([...set.entries()]); // [["A", "A"],["B", "B"],["C", "C"]]const map = new Map().set("name", "Tom").set("age", 19);
console.log([...map.keys()]); // ["name", "age"]
console.log([...map.values()]); // ["Tom", 19]
console.log([...map.entries()]); // [["name", "Tom"],["age", 19]]


每个数据结构都有一个默认的遍历器,例如数组的默认遍历器是values(),在没有明确指定遍历器的情况下,这些数据结构都会使用默认的遍历器。

我们可以通过检测对象的Symbol.iterator属性来判断对象是否拥有遍历器。

const arr = ["A", "B", "C"];
console.log(typeof arr[Symbol.iterator] === "function"); // true
console.log(arr[Symbol.iterator]); // function values() { ... }const set = new Set(arr);
console.log(typeof set[Symbol.iterator] === "function"); // true
console.log(set[Symbol.iterator]); // function values() { ... }const map = new Map().set("name", "Tom").set("age", 19);
console.log(typeof map[Symbol.iterator] === "function"); // true
console.log(map[Symbol.iterator]); // function entries() { ... }


原生具备遍历器的对象:

数组、Map集合、Set集合、字符串、arguments和 NodeList(节点列表)

对象(Object)默认是不可遍历的,我们可以通过Object.keys()、Object.values()和Object.entries() 方法把对象变成数组,使其拥有遍历器;或者直接为对象添加Symbol.iterator 属性来自定义遍历器。

const obj = {name: "Tom",age: 19
}
console.log(typeof Object.entries(obj)[Symbol.iterator] === "function"); // true
console.log([...Object.entries(obj)]); // [["name", "Tom"],["age", 19]] 

作者:朵宝特工007 https://www.bilibili.com/read/cv16952360 出处:bilibili

十六、以下为那些循环可以终止图 

​​​​​​​

 


http://chatgpt.dhexx.cn/article/8qAIQRhy.shtml

相关文章

JS中循环遍历数组的几种常用方式总结

第一种&#xff1a;for循环&#xff0c;也是最常见的 最简单的一种&#xff0c;也是使用频率最高的一种&#xff0c;虽然性能不弱&#xff0c;但仍有优化空间 const arr [11, 22, 33, 44, 55, 66, 77, 88]; for (let i 0; i < arr.length; i) {console.log(arr[i]);}打印…

3D人脸识别技术,正在全面入侵我们的日常生活

最近“人脸识别技术”因丰巢智能柜“刷脸取件”被小学生用一张面部打印照片破解的bug事件刷屏引发热议,整个过程无需本人在场便被轻易破解实在令人震惊,虽然目前该功能已经下线,但刷脸背后技术是否安全、面部信息泄露等问题仍是大众最为关心的问题。 事实上,现在人们听到“…

3D人脸识别——点云转化为可训练的图片

1.场景介绍 3D人脸点云不容易直接训练&#xff0c;需要将其转化为二维图片。大部分论文是这样做的&#xff1a;首先求出每个点所在平面的法向量&#xff0c;发向量与水平面和竖直平面的夹角组成两个通道&#xff0c;深度图是一个通道。然后&#xff0c;将这三个通道归一到[0~25…

人脸识别

自20世纪下半叶&#xff0c;计算机视觉技术逐渐地发展壮大。同时&#xff0c;伴随着数字图像相关的软硬件技术在人们生活中的广泛使用&#xff0c;数字图像已经成为当代社会信息来源的重要构成因素&#xff0c;各种图像处理与分析的需求和应用也不断促使该技术的革新。计算机视…

人脸识别技术

2D人脸识别技术早在安防、监控、门禁、考勤中就已有应用&#xff0c;其硬件结构相当于一颗RGB摄像头&#xff0c;通过捕捉人脸图像&#xff0c;从图像中提取对应的特征&#xff0c;依据尺度特征不变的原理&#xff0c;和已经录入的图像库进行对比判定。目前基于神经网络的人脸识…

什么是人脸识别?

什么是人脸识别&#xff1f; 人脸识别是一种用于识别陌生人或从特定人的脸中认证特定人的身份的方法。它是计算机视觉的一个分支&#xff0c;但是人脸识别是专门的&#xff0c;并且在某些应用程序中带有社交功能&#xff0c;并且存在一些欺骗的漏洞。 人脸识别如何工作&#…

揭秘“2020年度AI生产力创新奖”:清微智能3D人脸识别模组

“2020年度AI生产力创新奖“作为2020年行业内的最后一个奖项&#xff0c;在年前的最后两周才正式公布。姗姗来迟的评选结果&#xff0c;也从一个侧面证明了该奖项评比的激烈程度。清微智能与百度、京东、浪潮等企业一起&#xff0c;共同斩获IOT与智慧城市领域的”AI生产力创新奖…

android 脸部识别之3D,这两款安卓手机也支持3D结构光人脸识别

1、oppo Find X-4999元(8128G) oppo Find X为滑屏(双轨潜望结构)设计&#xff0c;3D结构光模组隐藏在内部&#xff0c;当需要解锁时会自动探出&#xff0c;不用时又会自动收回。 OPPO Find X的O-Face 3D结构光可以在人面部投射15,000个识别点&#xff0c;以此来为用户的面部构建…

android 脸部识别之3D,Android Q新功能曝光了:原生支持3D人脸识别

原标题&#xff1a;Android Q新功能曝光了&#xff1a;原生支持3D人脸识别 【PConline资讯】如今不少机型已经支持3D人脸识别&#xff0c;像iPhoneX、iPhoneXR、iPhoneXSMax、华为Mate20Pro、OPPOFindX、小米8透明探索版等等。 值得注意的是&#xff0c;目前原生Android并没有提…

嵌入式3D人脸识别(笔记)

3D人脸识别在人脸识别中所占比例58%&#xff08;2020年&#xff09;&#xff0c;3D是趋势。 3D人脸误识率1/100万&#xff0c;2D人脸误识率1/1万。 应用人脸活体、高精度识别。 几种深度相机比较&#xff1a; 双目&#xff1a;运算量大&#xff0c;受光照影响&#xff08;过…

AI深度 | 3D人脸识别和双目结构光惯导

文/纽豪斯 发布/AI智道 一文看尽双目摄像、结构光、ToF和激光雷达技术&#xff1b;一文深入了解小觅智能、奥比中光、华捷艾米、的卢深视、Pico和镭神智能&#xff1b;AI赋能2大趋势、4大核心技术。 前言 纽豪斯刚刚完成《AI深度&#xff08;上&#xff09; | 3D人脸识别和结构…

3D人脸识别——人脸点云前处理

1. 获取点云与显示点云 博主做项目是用realsense系列获取深度信息的&#xff0c;获得对齐的RGB图和深度图。 获取数据的代码如下&#xff1a; ## License: Apache 2.0. See LICENSE file in root directory. ## Copyright(c) 2017 Intel Corporation. All Rights Reserved.###…

3d人脸识别算法opencv_10行代码实现人脸识别

什么是人脸识别 人脸识别,是基于人的脸部特征信息进行身份识别的一种生物识别技术。用摄像机或摄像头采集含有人脸的图像或视频流,并自动在图像中检测和跟踪人脸,进而对检测到的人脸进行脸部识别的一系列相关技术,通常也叫做人像识别、面部识别。 目前的人脸识别技术已经非…

3D人脸识别准确率提升,成未来发展趋势

https://www.toutiao.com/a6678896218048823811/ 随着技术升级&#xff0c;生物识别技术已经被应用到越来越多的行业当中&#xff0c;渗透人们生活的方方面面&#xff0c;你的面部、眼睛、步态乃至表情都在告诉识别系统&#xff1a;你是谁。而近些年越来越火的人脸识别更是在证…

2D与3D人脸识别详解

人脸是人体最重要的生物特征之一,而人脸研究主要集中在人脸识别方面,人脸的表达模型分为2D人脸和3D人脸。2D人脸识别研究的时间相对较长,方法流程也相对成熟,在多个领域都有使用,但由于2D信息存在深度数据丢失的局限性,无法完整的表达出真实人脸,所以在实际应用中存在着…

一文读懂3D人脸识别十年发展及未来趋势

来源丨机器之心 人脸识别 是机器学习社区研究最多的课题之一&#xff0c;以 3D 人脸识别为代表的相关 ML 技术十年来都有哪些进展&#xff1f; 这篇文章给出了 答案。 近年来&#xff0c;人脸识别的研究已经转向使用 3D 人脸表面&#xff0c;因为 3D 几何信息可以表征更多的鉴别…

商汤科技3D人脸识别技术加持智能门锁,帮你解放双手

刚刚过去的元旦佳节&#xff0c;很多人选择聚餐聚会&#xff0c;共同迎接新年的到来&#xff0c;或是跟恋人一起度过浪漫的跨年夜。 在外有欢声笑语的氛围&#xff0c;回到家也应该有舒适的惬意。若是来到家门口&#xff0c;还要放下拎着的大包小包年货&#xff0c;腾出手来去…

3D人脸识别

目录 导语 3D人脸基础知识 初识3D人脸 相机模型 3D相机 3D人脸数据 3D人脸相关任务 常见Pipeline 3D人脸识别 3D人脸重建 总结 导语 随着深度学习技术的推进&#xff0c;人脸相关任务研究也跃升为学界和业界的热点。人们所熟知的人脸任务一般包括人脸检测&#xff0…

一文为你详解2D与3D人脸识别有什么区别?

最近业界内刮起了一股“人脸识别安全”的大讨论&#xff0c;小到个人大到超市以及银行&#xff0c;都在使用这个刷脸认证或支付&#xff0c;说它好吧&#xff0c;确实解决了无接触&#xff0c;快速高效等问题&#xff0c;你说它不好吧&#xff0c;也是有原因的&#xff0c;比如…

图像算法之3D人脸识别技术原理概述

随着深度学习技术的进步&#xff0c;面部相关任务的研究也成为学术界和工业界的热门话题。众所周知的面部任务通常包括面部检测&#xff0c;面部识别&#xff0c;面部表情识别等&#xff0c;其主要使用2D RGB面部&#xff08;通常包括一些纹理信息&#xff09;作为输入; 3D扫描…