您现在的位置是:网站首页 > 数组遍历方法文章详情
数组遍历方法
陈川
【
JavaScript
】
4839人已围观
4379字
数组是JavaScript中最常用的数据结构之一,处理数组时经常需要遍历元素。JavaScript提供了多种遍历方法,每种方法都有其适用场景和特点。
for循环
最基本的遍历方式是传统的for
循环,通过索引访问数组元素:
const fruits = ['apple', 'banana', 'orange'];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
这种方式可以精确控制循环过程,包括中断循环或跳过某些元素:
for (let i = 0; i < fruits.length; i++) {
if (i === 1) continue; // 跳过第二个元素
if (fruits[i] === 'orange') break; // 遇到orange时终止循环
console.log(fruits[i]);
}
for...of循环
ES6引入的for...of
语法更简洁,直接获取元素值:
for (const fruit of fruits) {
console.log(fruit);
}
这种写法避免了索引操作,但不能直接获取当前元素的索引。如需索引可以结合entries()
方法:
for (const [index, fruit] of fruits.entries()) {
console.log(index, fruit);
}
forEach方法
数组的forEach
方法接受一个回调函数,为每个元素执行操作:
fruits.forEach(function(fruit, index) {
console.log(index, fruit);
});
使用箭头函数可以更简洁:
fruits.forEach((fruit, index) => console.log(index, fruit));
注意forEach
无法使用break
中断循环,也不能使用return
返回外层函数。
map方法
map
方法将数组映射为新数组,不改变原数组:
const upperFruits = fruits.map(fruit => fruit.toUpperCase());
console.log(upperFruits); // ['APPLE', 'BANANA', 'ORANGE']
回调函数接收三个参数:当前元素、索引和数组本身:
const fruitWithIndex = fruits.map((fruit, index, arr) => {
return `${index + 1}/${arr.length}: ${fruit}`;
});
filter方法
filter
根据条件筛选数组元素:
const longFruits = fruits.filter(fruit => fruit.length > 5);
console.log(longFruits); // ['banana', 'orange']
reduce方法
reduce
将数组归约为单个值,常用于计算总和或构建对象:
const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 10
复杂归约示例:
const people = [
{ name: 'Alice', age: 21 },
{ name: 'Bob', age: 25 },
{ name: 'Charlie', age: 21 }
];
const ageGroups = people.reduce((groups, person) => {
const age = person.age;
if (!groups[age]) {
groups[age] = [];
}
groups[age].push(person);
return groups;
}, {});
console.log(ageGroups);
// {
// '21': [{name: 'Alice', age: 21}, {name: 'Charlie', age: 21}],
// '25': [{name: 'Bob', age: 25}]
// }
some和every方法
some
测试是否有元素满足条件,every
测试是否所有元素都满足条件:
const hasApple = fruits.some(fruit => fruit === 'apple');
const allLongNames = fruits.every(fruit => fruit.length > 3);
find和findIndex方法
find
返回第一个满足条件的元素,findIndex
返回其索引:
const firstLongFruit = fruits.find(fruit => fruit.length > 5);
const firstLongIndex = fruits.findIndex(fruit => fruit.length > 5);
性能考虑
不同遍历方法性能差异明显。基准测试表明,在超大数组(如100万元素)上:
for
循环最快forEach
比for
慢约3-5倍map
/filter
等函数式方法更慢,但代码更简洁
// 性能测试示例
const hugeArray = new Array(1000000).fill(0);
console.time('for');
for (let i = 0; i < hugeArray.length; i++) {}
console.timeEnd('for');
console.time('forEach');
hugeArray.forEach(() => {});
console.timeEnd('forEach');
特殊遍历场景
处理稀疏数组时需注意:
const sparseArray = [1, , 3]; // 注意第二个元素是empty
sparseArray.forEach(x => console.log(x)); // 跳过empty
for (const x of sparseArray) console.log(x); // undefined代替empty
遍历类数组对象可先转换为数组:
function printArgs() {
Array.from(arguments).forEach(arg => console.log(arg));
}
printArgs(1, 2, 3);
现代JavaScript特性
ES2019增加了flat
和flatMap
方法:
const nested = [1, [2, 3], [4, [5]]];
const flat = nested.flat(2); // [1, 2, 3, 4, 5]
const sentences = ["Hello world", "Good morning"];
const words = sentences.flatMap(s => s.split(' '));
// ["Hello", "world", "Good", "morning"]
ES2023新增的findLast
和findLastIndex
:
const numbers = [1, 2, 3, 2, 1];
const lastTwo = numbers.findLast(n => n === 2); // 2
const lastTwoIndex = numbers.findLastIndex(n => n === 2); // 3
迭代器协议
数组实现了迭代器协议,可以手动控制迭代:
const iterator = fruits[Symbol.iterator]();
let result = iterator.next();
while (!result.done) {
console.log(result.value);
result = iterator.next();
}
并行处理
现代JavaScript支持并行处理数组:
// 使用Web Worker并行处理
if (window.Worker) {
const worker = new Worker('worker.js');
worker.postMessage(hugeArray);
worker.onmessage = e => console.log(e.data);
}
类型化数组
处理二进制数据时使用类型化数组:
const buffer = new ArrayBuffer(16);
const int32View = new Int32Array(buffer);
int32View.forEach((val, i) => {
int32View[i] = i * 2;
});
上一篇: 数组基本操作(增删改查)
下一篇: 数组排序与搜索