Writing Iterator and Generator using JavaScript
Published: 2021-05-01 04:29:33

<img class="aligncenter size-full wp-image-13728" src="https://off.tokyo/wp-content/uploads/2021/04/javascript.jpg" alt="" width="1280" height="720" />

source : [Writing Iterator and Generator using JavaScript | off.tokyo](https://off.tokyo/blog/writing-iterator-and-generator-using-javascript/)

Iteration is the foundation of programming. The degree to which a programming language helps you iterate makes a big difference in your programming comfort.

&nbsp;

JavaScript has been a lagging language when it comes to iteration. However, with the introduction of Iterator and Generator, this is about to change.

&nbsp;
<h2>Iterator</h2>
&nbsp;
<h3>Itreable and Iterator</h3>
&nbsp;

In JavaScript, an object that can be iterated over is called an iterable, and typical examples of iterables are Arrays and Maps. A typical example of an Iterable is an Array or Map, which is iterable because it has multiple values.

&nbsp;

An Iterable object has an Iterator, which can be obtained with Iterable[Symbol.iterator]().

&nbsp;
<div class="wp-block-codemirror-blocks code-block ">
<pre class="CodeMirror" data-setting="{&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}">const array = [1, 2, 3];
const iterator = array[Symbol.iterator]();</pre>
</div>
&nbsp;

Iterator has only one method, next(), which can be used to retrieve the next value in an Iterable.

&nbsp;

&nbsp;
<div class="wp-block-codemirror-blocks code-block ">
<pre class="CodeMirror" data-setting="{&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}">const array = [1, 2, 3];
const iterator = array[Symbol.iterator]();

console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3</pre>
</div>
&nbsp;

The value obtained by next() is an object that is {value: the next value, done: whether it has finished or not}.

&nbsp;

By checking the value of value, we can get the value of Iterable.

&nbsp;

By checking the value of value, we can get the value of the Iterable, and by checking the value of done, we can get the value of the bool to see if the iteration has finished or not.

&nbsp;

In other words, the above code can be rewritten using a loop as follows

&nbsp;
<div class="wp-block-codemirror-blocks code-block ">
<pre class="CodeMirror" data-setting="{&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}">const array = [1, 2, 3];
const iterator = array[Symbol.iterator]();

let next = iterator.next();
while(!next.done) {
  console.log(next.value); // 1 2 3
  next = iterator.next();
}</pre>
</div>
&nbsp;

Iterator is a smart way to write iterations.

&nbsp;

However, this is still cumbersome. Therefore, javaScript provides a simpler way to write Iterator iteration.
<h3>The for-of statement</h3>
&nbsp;

The for-of statement is the easiest way to handle an Iterable.

&nbsp;

Rather than explaining it in words, it will be easier to understand if you look at the code first.

&nbsp;

&nbsp;
<div class="wp-block-codemirror-blocks code-block ">
<pre class="CodeMirror" data-setting="{&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}">const array = [1, 2, 3];

for(const val of array) {
  console.log(val); // 1 2 3
}</pre>
</div>
&nbsp;

&nbsp;
<h3>Creating your own Iterators and Iterables</h3>
&nbsp;

It is also possible to create your own Iterators and Iterables.

&nbsp;

Creating an Iterator is as simple as implementing a next() method that returns {value, done}.

&nbsp;

Iterable is also a simple matter of implementing [Symbol.iterator]().

&nbsp;

For example, let's consider implementing the range() function.

&nbsp;

The functions to create an Iterator and an Iterable look like the following

&nbsp;
<div class="wp-block-codemirror-blocks code-block ">
<pre class="CodeMirror" data-setting="{&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}">function createRangeIterator(end) {
  let currentValue = 0;
  const iterator = new Object();

  iterator.next = () =&gt; {
    const value = currentValue++;
    const done = currentValue &gt; end;
    const result = done ? {done: done} : {value: value, done: done};
    return result;
  };
  
  return iterator;
}

function range(end) {
  const iterable = new Object();
  iterable[Symbol.iterator] = () =&gt;  createRangeIterator(end);
  
  return iterable;
}

for(const val of range(3)) {
  console.log(val); // 0 1 2
}</pre>
</div>
&nbsp;

Since the Iterator mechanism is simple, it is easy to create your own.

&nbsp;
<h2>Generator</h2>
&nbsp;
<h3>Generator function and yield return</h3>
&nbsp;

Even though the Iterator mechanism itself is simple, the actual implementation is quite lengthy. Of course, there are excellent programmers who can read and write this code easily, but it is difficult for most people to do so.

The Generator provides a very easy way to work with Iterators and Iterables, allowing you to automatically iterate over them with simple code.

To use the Generator, use function* instead of function, and yield instead of return. To use Generator, use function* instead of function,

&nbsp;

and yield instead of return. This is all you need to complete the Generator. Here, the function defined by function* is called the Generator function.

&nbsp;
<div class="wp-block-codemirror-blocks code-block ">
<pre class="CodeMirror" data-setting="{&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}">function* generator() {
  yield 1;
  yield 2;
  yield 3;
}

for(const val of generator()) {
  console.log(val); // 1 2 3
}</pre>
</div>
&nbsp;

The Generator function returns a Generator object.

&nbsp;

The Generator object is an Iterable and an Iterator object.

&nbsp;

The generator object is both an Iterator and an Iterator object, and can be used as an Iterator, such as generator.next().value, or as an Iterable, such as using for-of to retrieve a value.

&nbsp;

When next() is called, the Generator function will stop and return the yielded value each time it is yielded.

&nbsp;

When next() is called again, it resumes function execution and proceeds to the next yield.

&nbsp;

The Generator behaves like an Iterator by repeating this process.

&nbsp;
<h3>yield* to yield an Iterable</h3>
&nbsp;

You can also use yield* instead of yield to automatically yield the contents of an Iterable one by one.

&nbsp;
<div class="wp-block-codemirror-blocks code-block ">
<pre class="CodeMirror" data-setting="{&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}">function* generator() {
  yield* [1, 2, 3];
}

for(const val of generator()) {
  console.log(val); // 1 2 3
}</pre>
</div>
&nbsp;
<h3>Saving the Context</h3>
&nbsp;

yield and yield* preserve the context of the function. This means that the values of variables in the function will be preserved. As a concrete example, you can write a generator like the following

&nbsp;
<div class="wp-block-codemirror-blocks code-block ">
<pre class="CodeMirror" data-setting="{&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}">function* generator() {
  for(let i=0; i&lt; 3; i++) {
    yield i;
  }
}

for(const val of generator()) {
  console.log(val); // 0 1 2
}</pre>
</div>
&nbsp;

By using this, for example, the previous range function can be easily written as follows

&nbsp;
<div class="wp-block-codemirror-blocks code-block ">
<pre class="CodeMirror" data-setting="{&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}">function* range(end) {
  for(let i=0; i &lt; end; i++) {
    yield i;
  }
}

for(const val of range(3)) {
  console.log(val); // 0 1 2
}</pre>
</div>
&nbsp;

I was able to write it much more easily.

&nbsp;
<h2>Summary</h2>
&nbsp;
<ul>
 	<li>Iterable objects are Iterable</li>
 	<li>Iterable objects have an Iterator.</li>
 	<li>Iterable can be easily iterated by using for-of statement</li>
 	<li>Iterator and Iterable can be created by oneself.</li>
 	<li>Iterables can be easily created using the Generator.</li>
 	<li>Generator is both an Iterable and an Iterator</li>
 	<li>Generator is both an Iterable and an Iterator ・Yield can be used to return the next value</li>
 	<li>The generator is an Iterable and an Iterator.</li>
 	<li>The context is preserved even if the function is temporarily exited by yield.</li>
</ul>
&nbsp;

＊This article is a summary of the Japanese article with only the main points explained in an easy-to-understand manner.

https://sbfl.net/blog/2016/08/17/javascript-iterator-generator/