阿里云主机折上折
  • 微信号
Current Site:Index > Array traversal methods

Array traversal methods

Author:Chuan Chen 阅读数:38555人阅读 分类: JavaScript

Arrays are one of the most commonly used data structures in JavaScript, and traversing elements is often required when working with them. JavaScript provides multiple traversal methods, each with its own characteristics and suitable scenarios.

for Loop

The most basic traversal method is the traditional for loop, which accesses array elements via indices:

const fruits = ['apple', 'banana', 'orange'];
for (let i = 0; i < fruits.length; i++) {
  console.log(fruits[i]);
}

This method allows precise control over the loop, including interrupting the loop or skipping certain elements:

for (let i = 0; i < fruits.length; i++) {
  if (i === 1) continue; // Skip the second element
  if (fruits[i] === 'orange') break; // Terminate the loop when encountering 'orange'
  console.log(fruits[i]);
}

for...of Loop

The for...of syntax introduced in ES6 provides a more concise way to traverse arrays:

for (const fruit of fruits) {
  console.log(fruit);
}

This syntax directly retrieves the element values rather than indices, but it cannot directly access the current element's index. To obtain the index, you can combine it with the array's entries() method:

for (const [index, fruit] of fruits.entries()) {
  console.log(index, fruit);
}

forEach Method

The forEach method of arrays accepts a callback function as a parameter:

fruits.forEach(function(fruit, index) {
  console.log(index, fruit);
});

Using arrow functions makes it even more concise:

fruits.forEach((fruit, index) => {
  console.log(index, fruit);
});

forEach cannot be interrupted using break or return. To terminate early, you need to throw an exception:

try {
  fruits.forEach(fruit => {
    if (fruit === 'banana') throw new Error('Stop iteration');
    console.log(fruit);
  });
} catch (e) {
  if (e.message !== 'Stop iteration') throw e;
}

map Method

The map method traverses the array and returns a new array:

const upperFruits = fruits.map(fruit => fruit.toUpperCase());
console.log(upperFruits); // ['APPLE', 'BANANA', 'ORANGE']

The callback function receives three parameters: the current element, its index, and the array itself:

const fruitWithIndex = fruits.map((fruit, index) => `${index}:${fruit}`);
console.log(fruitWithIndex); // ['0:apple', '1:banana', '2:orange']

filter Method

The filter method returns a new array composed of elements that meet the specified condition:

const longFruits = fruits.filter(fruit => fruit.length > 5);
console.log(longFruits); // ['banana', 'orange']

reduce Method

The reduce method accumulates array elements into a single value:

const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((accumulator, current) => accumulator + current, 0);
console.log(sum); // 10

The initial value can be omitted, in which case the first element of the array is used as the initial value:

const product = numbers.reduce((acc, curr) => acc * curr);
console.log(product); // 24

some and every Methods

some tests whether at least one element meets the condition:

const hasApple = fruits.some(fruit => fruit === 'apple');
console.log(hasApple); // true

every tests whether all elements meet the condition:

const allLong = fruits.every(fruit => fruit.length > 3);
console.log(allLong); // true

find and findIndex Methods

find returns the first element that meets the condition:

const firstLong = fruits.find(fruit => fruit.length > 5);
console.log(firstLong); // 'banana'

findIndex returns the index of the first element that meets the condition:

const firstLongIndex = fruits.findIndex(fruit => fruit.length > 5);
console.log(firstLongIndex); // 1

keys, values, and entries Methods

These methods return iterator objects:

for (const index of fruits.keys()) {
  console.log(index); // 0, 1, 2
}

for (const value of fruits.values()) {
  console.log(value); // 'apple', 'banana', 'orange'
}

for (const [index, value] of fruits.entries()) {
  console.log(index, value); // 0 'apple', 1 'banana', 2 'orange'
}

Performance Considerations

Different traversal methods vary in performance. For large arrays, the traditional for loop is usually the fastest:

console.time('for loop');
for (let i = 0; i < 1000000; i++) {}
console.timeEnd('for loop');

console.time('forEach');
Array(1000000).forEach(() => {});
console.timeEnd('forEach');

Handling Sparse Arrays

Sparse arrays (those with empty slots) are handled differently:

const sparse = [1,,3];
sparse.forEach(x => console.log(x)); // 1, 3
for (const x of sparse) console.log(x); // 1, undefined, 3

Modifying the Original Array

Modifying the original array during traversal can lead to unexpected behavior:

const numbers = [1, 2, 3];
numbers.forEach((num, index) => {
  numbers.push(num * 2); // Will cause an infinite loop
});

Array-like Objects

When dealing with array-like objects (e.g., arguments, NodeList):

function logArgs() {
  Array.prototype.forEach.call(arguments, arg => {
    console.log(arg);
  });
}
logArgs(1, 2, 3);

Modern JavaScript recommends using Array.from:

const nodeList = document.querySelectorAll('div');
Array.from(nodeList).forEach(div => {
  console.log(div);
});

Asynchronous Traversal

When handling asynchronous operations, forEach does not wait for Promises:

const urls = ['url1', 'url2'];
urls.forEach(async url => {
  await fetch(url); // Will not execute in order
});

You can use for...of with await instead:

for (const url of urls) {
  await fetch(url); // Executes in order
}

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.