Iterator summary

preface

Data traversal is a logic often used in our daily development. In addition to the most common for, while and forEach, iterators also provide an interface for data traversal. Understanding iterators will help us better deal with data.

Iterator

Iterator is a new traversal mechanism introduced by ES6. Iterator has two core concepts:

  • Iterator is a unified interface. Its function is to make various data structures accessible conveniently. It is through a key as symbol Iterator method.
  • An iterator is a pointer (such as a cursor in a database) used to traverse elements of a data structure.

iterative process

The iterative process is as follows:

  • Through symbol Iterator creates an iterator that points to the starting position of the current data structure
  • Then iterate down through the next method to point to the next location. The next method will return the object at the current location. The object contains two attributes: value and done. Value is the value of the current attribute, and done is used to judge whether the traversal is over
  • When done is true, the traversal ends

The following is a simple example:

const items = ["zero", "one", "two"]; 
const it = items[Symbol.iterator]();  
it.next(); 
>{value: "zero", done: false} 
it.next(); 
>{value: "one", done: false} 
it.next(); 
>{value: "two", done: false} 
it.next(); 
>{value: undefined, done: true}

In the above example, first create an array, and then use symbol The iterator method creates an iterator, and then continuously calls the next method to access the internal items of the array. When the attribute done is true, the access ends.

Iterators are part of the protocol (the rules that use them) and are used for iterations. A key feature of the protocol is that it is sequential: the iterator returns one value at a time. This means that if the iteratable data structure is nonlinear (such as a tree), the iteration will linearize it.

Iterative data structure

The following values can be iterated:

  • Array
  • String
  • Map
  • Set
  • Dom element (in progress)

We will use for The of loop (see for...of loop below) iterates over the data structure.

Array

Array and typedaray they are iterative.

for (let item of ["zero", "one", "two"]) {  
    console.log(item); 
} 
// output: 
// zero 
// one 
// two

String

Strings are iteratable, but they traverse Unicode codes, and each code may contain one or two Javascript characters.

for (const c of 'z\uD83D\uDC0A') {
    console.log(c); 
} 
// output: 
// z 
// \uD83D\uDC0A

Map

Map mainly iterates their entries. Each entry will be encoded as key and value items. Entries iterate according to the determined situation in the same order as the addition order.

const map = new Map(); 
map.set(0, "zero"); 
map.set(1, "one");  
for (let item of map) {  
    console.log(item); 
} 
// output: 
// [0, "zero"] 
// [1, "one"]

Note: WeakMaps is not iterative

Set

Set iterates over its elements in the same order as they are added

const set = new Set(); 
set.add("zero"); 
set.add("one");  
for (let item of set) {
    console.log(item);
} 
// output: 
// zero 
// one

Note: WeakSets are not iterative

arguments

arguments is less and less used in traversal, but it can also be used in ES6

function args() {
    for (let item of arguments) {
        console.log(item);
    }
} args("zero", "one"); 
// output: 
// zero 
// one

Ordinary objects cannot be iterated

Ordinary objects are created by objects and cannot be iterated:

// TypeError 
for (let item of {}) {
    console.log(item); 
}

for...of cycle

for...of is a new loop introduced by ES6 to replace for In and forEach(), and support new iterative protocols. It can be used to iterate over conventional data types, such as Array, String, Map, Set, and so on.

Iterative general data type

Array

const nums = ["zero", "one", "two"];
for (let num of nums) {
    console.log(num); 
} 
// TypedArray 
const typedArray1 = new Int8Array(6); 
typedArray1[0] = 10; 
typedArray1[1] = 11;
for (let item of typedArray1) {
    console.log(item);
}

String

const str = "zero";  
for (let item of str) {
    console.log(item);
}

Map

let myMap = new Map(); 
myMap.set(0, "zero"); 
myMap.set(1, "one"); 
myMap.set(2, "two");  
// Traverse key and value 
for (let [key, value] of myMap) {
    console.log(key + " = " + value);
}
for (let [key, value] of myMap.entries()) {
    console.log(key + " = " + value);
}  
// Only traverse key 
for (let key of myMap.keys()) {
    console.log(key);
}  
// Only traverse value 
for (let value of myMap.values()) {
    console.log(value);
}

Set

let mySet = new Set(); 
mySet.add("zero"); 
mySet.add("one"); 
mySet.add("two");  
// Traverse the entire set 
for (let item of mySet) {
    console.log(item);
}  
// Only the key value is traversed 
for (let key of mySet.keys()) {
    console.log(key);
}  
// Only traverse value 
for (let value of mySet.values()) {
    console.log(value);
}  
// Traverse key and value, and they will be equal 
for (let [key, value] of mySet.entries()) {
    console.log(key + " = " + value);
}

Iterative data structure

The of operand must be iteratable, which means that if it is a normal object, it cannot be iterated. If the data structure is similar to the form of array, you can use array The from () method performs transformation iterations.

const arrayLink = {
    length: 2, 
    0: "zero", 
    1: "one"
}
// TypeError exception reported 
for (let item of arrayLink) {
    console.log(item);
}  
// normal operation 
for (let item of Array.from(arrayLink)) {
    console.log(item);
}
// output: 
// zero 
// one 

let, const, and var are used for of

If let and const are used, each iteration will create a new storage space, which can ensure that the scope is within the iteration.

const nums = ["zero", "one", "two"];
for (const num of nums) {
    console.log(num);
} 
// Report ReferenceError 
console.log(num);

From the above example, we can see that the last sentence will report an exception. The reason is that the scope of num is only inside the loop body, and the outside is invalid. With VaR, the above situation will not occur, because var will act on the global, and the iteration will not create a new storage space every time.

const nums = ["zero", "one", "two"];
forv (var num of nums) {
    console.log(num);
} 
console.log(num);
// output: two

summary

The above is a summary of iterators. I hope we can use them flexibly in our usual development.

~End of this article, thank you for reading!

Added by batman on Sun, 27 Feb 2022 03:52:23 +0200