背景:日常开发中处理数组常用到的遍历方法,看这篇就够了
目录
数组遍历方法
for
最基本的循环结构,通常用于遍历数组,可以使用break终止循环
let arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; i++) {
// i 下标
// arr[i] 每个元素
console.log(arr[i]);
}
forEach
用于执行数组中的每个元素的回调函数。不能在其内部使用break或return语句来终止遍历
let arr = [1, 2, 3, 4, 5];
arr.forEach(function(value, index) {
console.log(value);
})
for…of
ES6引入的新特性,用于遍历可迭代对象,如数组
let arr = [1, 2, 3, 4, 5];
for (let value of arr) {
console.log(value);
}
map
对数组的每个元素执行回调函数,并返回包含结果的新数组
let arr = [1, 2, 3, 4, 5];
let newArr = arr.map(function(value, index) {
return value * 2;
});
console.log(newArr); // [2, 4, 6, 8, 10]
filter
测试数组的每个元素是否符合某个条件,并返回符合条件的所有元素的新数组
let arr = [1, 2, 3, 4, 5];
let newArr = arr.filter(function(value, index) {
return value > 3;
});
console.log(newArr); // [4, 5]
for…in
不推荐用于数组遍历,因为它遍历的是键名,对于非常大的数组可能会有问题
let arr = [1, 2, 3, 4, 5];
for (let index in arr) {
console.log(arr[index]);
}
reduce
对数组的所有元素调用指定的回调函数并最终返回一个值
功能较强大,例如:
求和、求积
let arr = [1, 2, 3, 4, 5];
let sum = arr.reduce(function(accumulator, currentValue) {
// return accumulator * currentValue; // 求积
return accumulator + currentValue; // 求和
}, 0);
console.log(sum); // 15
数组去重
let arr = [2,3,2,5,5,22,31]
let newArr = arr.reduce((pre, cur) => {
if(!pre.includes(cur)){
pre.push(cur)
}
return pre
},[])
console.log(newArr) // [2, 3, 5, 22, 31]
计算数组中每个元素出现的次数
let objArr = ['张三', '李四', '王五', '李四', '张三']
let newObj = objArr.reduce((pre, cur)=>{
if(cur in pre){
pre[cur] ++
}else{
pre[cur] = 1
}
return pre
},{})
console.log(newObj) // {张三: 2, 李四: 2, 王五: 1}
将二维数组转化为一维
let arr = [[1,2],[2,3],[22,33]]
let newObj = arr.reduce((pre,cur) => {
return pre.concat(cur)
},[])
console.log(newObj) // [1, 2, 2, 3, 22, 33]
将多维数组转化为一维
let arr = [[1,2],[2,[22,33]]]
let objFn = function (arr){
return arr.reduce((pre, cur) => pre.concat(Array.isArray(cur) ? objFn(cur) : cur) ,[])
}
console.log(objFn(arr)) // [1, 2, 2, 22, 33]
对象里的属性求和
let objArr = [{id: 1, num: 2},{id: 2, num: 5},{id: 3, num: 7}]
let newObjArr = objArr.reduce((pre, cur)=>{
return pre + cur.num
}, 0)
console.log(newObjArr) // 14
按对象属性给数组分组
let objArr = [
{sex: '男', name: '张三'},
{sex: '女', name: '小红'},
{sex: '男', name: '李四'},
{sex: '女', name: '小丽'}
]
function arrBy(arr, property){
return arr.reduce((pre, cur)=>{
let key = cur[property]
if(!pre[key]){
pre[key] = []
}
pre[key].push(cur)
return pre
}, {})
}
console.log(arrBy(objArr, 'sex'))
简单对比
- 当你需要修改数组时使用map
- 需要过滤数组时使用filter
- 需要计算数组总和使用reduce
- 而简单遍历操作则可以使用for循环或者forEach,不考虑性能,foreach相对更优雅
- 由于for…in…得到的是key,故常用来遍历对象
- for…of…得到的是val,可以用来遍历数组
for和forEach谁的效率更高(面试可能会问)?
let for_arr=new Array(9999999).fill(0);
console.time('for');
for(let i=0;i<for_arr.length;i++){}
console.timeEnd('for');
let foreach_arr=new Array(9999999).fill(0);
console.time('foreach');
foreach_arr.forEach(ele => {})
console.timeEnd('foreach');
for效率相对更高,forEach相对优雅
- forEach每次循环都会声明一个函数,for则不需要
- 在 for 循环中,可以通过定义一个本地变量(如var len = arr.length)将数组长度缓存起来,避免多次访问 arr.length 属性导致的性能损失。
需要注意的是,虽然 for 循环比 forEach 循环更快,但在实际应用中,在性能方面的差别通常不会太大。所以具体使用哪个,需要结合实际情况分析
如果有不对的地方欢迎留言交流,
当然如果对你有帮助,赏个三连