阿里云主机折上折
  • 微信号
Current Site:Index > Iteration methods for collection types

Iteration methods for collection types

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

ECMAScript 6 introduced new collection types (such as Set, Map, WeakSet, and WeakMap) and provided them with various iteration methods. These methods make traversing collection elements more flexible and efficient while maintaining high consistency with traditional array iteration approaches.

Iteration Methods for Set

Set is an unordered collection with unique elements. ES6 provides the following iteration methods for Set:

forEach Method

Set.prototype.forEach allows executing a callback function for each element in the set, with syntax similar to the array's forEach:

const mySet = new Set([1, 2, 3]);
mySet.forEach((value, valueAgain, set) => {
  console.log(value); // 1, 2, 3
});

Note: In Set's forEach, the second parameter valueAgain is the same as the first parameter. This is to maintain consistency with Map's forEach.

keys, values, and entries Methods

Set provides the following iterator-generating methods:

const mySet = new Set(['a', 'b', 'c']);

// keys() returns an iterator of values
for (const key of mySet.keys()) {
  console.log(key); // 'a', 'b', 'c'
}

// values() is the same as keys()
for (const value of mySet.values()) {
  console.log(value); // 'a', 'b', 'c'
}

// entries() returns an iterator in the form of [value, value]
for (const entry of mySet.entries()) {
  console.log(entry); // ['a', 'a'], ['b', 'b'], ['c', 'c']
}

Direct Iteration of Set Objects

Set objects themselves are iterable, and their default iterator is the same as values():

const mySet = new Set([true, false]);
for (const item of mySet) {
  console.log(item); // true, false
}

Iteration Methods for Map

Map is a collection of key-value pairs, and its iteration methods are more extensive than those of Set:

forEach Method

Map.prototype.forEach can traverse all key-value pairs:

const myMap = new Map([
  ['name', 'Alice'],
  ['age', 25]
]);

myMap.forEach((value, key, map) => {
  console.log(`${key}: ${value}`); // "name: Alice", "age: 25"
});

keys, values, and entries Methods

const myMap = new Map([
  [1, 'one'],
  [2, 'two']
]);

// keys() returns an iterator of keys
for (const key of myMap.keys()) {
  console.log(key); // 1, 2
}

// values() returns an iterator of values
for (const value of myMap.values()) {
  console.log(value); // 'one', 'two'
}

// entries() returns an iterator in the form of [key, value]
for (const entry of myMap.entries()) {
  console.log(entry); // [1, 'one'], [2, 'two']
}

Direct Iteration of Map Objects

The default iterator for Map is the same as entries():

const myMap = new Map([[false, 'no'], [true, 'yes']]);
for (const [key, value] of myMap) {
  console.log(key, value); // false 'no', true 'yes'
}

Special Characteristics of WeakSet and WeakMap

WeakSet and WeakMap do not provide any iteration methods because their keys are weakly referenced. The JavaScript engine may reclaim these objects at any time, making it impossible to guarantee stable iteration.

const weakSet = new WeakSet([{}, {}]);
// weakSet.forEach(...) // Error: weakSet.forEach is not a function

const weakMap = new WeakMap();
// for (const item of weakMap) {...} // Error: weakMap is not iterable

Combining Iterators with Destructuring Assignment

Collection iterators can be perfectly combined with destructuring assignment:

const userMap = new Map([
  ['id', 123],
  ['name', 'Bob'],
  ['email', 'bob@example.com']
]);

// Convert to an array for processing
const userArray = [...userMap];
console.log(userArray); // [['id', 123], ['name', 'Bob'], ['email', 'bob@example.com']]

// Directly destructure key-value pairs
for (const [key, value] of userMap) {
  console.log(`User ${key}: ${value}`);
}

Custom Iteration Logic

By returning custom iterators, you can control the iteration behavior of collections:

class CustomSet extends Set {
  *filter(predicate) {
    for (const value of this) {
      if (predicate(value)) {
        yield value;
      }
    }
  }
}

const numbers = new CustomSet([1, 2, 3, 4, 5]);
for (const num of numbers.filter(x => x % 2 === 0)) {
  console.log(num); // 2, 4
}

Performance Considerations

Different iteration methods may have performance variations on large collections:

const largeMap = new Map();
for (let i = 0; i < 1000000; i++) {
  largeMap.set(i, `value${i}`);
}

// Test for...of speed
console.time('for...of');
for (const [key, value] of largeMap) {
  // Empty loop
}
console.timeEnd('for...of');

// Test forEach speed
console.time('forEach');
largeMap.forEach((value, key) => {
  // Empty callback
});
console.timeEnd('forEach');

Typically, for...of performs similarly to forEach in the latest JavaScript engines, but there may be differences across browsers.

Integration with Other ES6 Features

Collection iterators can be combined with features like generators and asynchronous iteration:

async function* asyncMapValues(map) {
  for (const value of map.values()) {
    // Simulate asynchronous operation
    yield await Promise.resolve(value);
  }
}

const asyncMap = new Map([[1, 'A'], [2, 'B']]);
(async () => {
  for await (const value of asyncMapValues(asyncMap)) {
    console.log(value); // 'A', 'B'
  }
})();

Common Usage Patterns

Collection iteration methods have various applications in real-world development:

  1. Data Transformation:
const setToArray = [...new Set([1, 2, 2, 3])]; // [1, 2, 3]
  1. Map Conversion:
const mapToObject = Object.fromEntries(
  new Map([['a', 1], ['b', 2]]).entries()
); // {a: 1, b: 2}
  1. Filtering Operations:
const filteredMap = new Map(
  [...originalMap].filter(([key, value]) => value > 10)
);
  1. Batch Operations:
function bulkSetOperation(setA, setB, operation) {
  const result = new Set();
  for (const item of setA) {
    if (operation === 'union' || setB.has(item)) {
      result.add(item);
    }
  }
  return result;
}

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

如果侵犯了你的权益请来信告知我们删除。邮箱: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 ☕.