Creating a linked list in ES6

I have a linked list in JavaScript that I need to make iterable with a for of loop. I almost did this, but there seems to be no way to get the first value included in the result. Here is a simplified version:

 var obj = {value: 1, next: {value: 2, next: {value: 3, next: {value: 4, next: {value: 5, next: {value: 6, next: {value:7, next: null}}}}}}}; obj[Symbol.iterator] = function() { var current = this; return { next() { if (current.next !== null) { current = current.next; return {value: current.value, done: false}; } return {done: true} } } } for (const x of obj) { console.log(x) } // this is how you get the values printed with no loop // console.log(obj.value + '->' + obj.next.value + '->' + obj.next.next.value) 
+5
source share
2 answers

The problem is that you move current to the next node before retrieving the value .

 var obj = {value: 1, next: {value: 2, next: {value: 3, next: {value: 4, next: {value: 5, next: {value: 6, next: {value:7, next: null}}}}}}}; obj[Symbol.iterator] = function() { var current = this; return { next() { if (current) { var value = current.value; current = current.next; return {value: value, done: false}; } return {done: true}; } }; }; for (const x of obj) { console.log(x); } 

It is much easier to implement an iterator with a function.

 var obj = {value: 1, next: {value: 2, next: {value: 3, next: {value: 4, next: {value: 5, next: {value: 6, next: {value:7, next: null}}}}}}}; obj[Symbol.iterator] = function*() { var current = this; while (current) { yield current.value; current = current.next; } }; for (const x of obj) { console.log(x); } 
+4
source

You should test current , not current.next :

 obj[Symbol.iterator] = function() { var current = this; return { next() { if (current !== null) { var res = {value: current.value, done: false}; current = current.next; return res; } else { return {done: true}; } } }; } 

But he can do it a lot easier than the generator method:

 obj[Symbol.iterator] = function* () { for (var current = this; current !== null; current = current.next) { yield current.value; } } 

Btw, I would recommend not putting this iterator on each node of the list (or even on the first). Insert a separate object that points to the head of the list, or make it a static helper function:

 let list = { head: obj, // could be null either *[Symbol.iterator]() { for (var current = this.head; current !== null; current = current.next) { yield current.value; } } } 

 function* linkedList(head) for (; head !== null; head = head.next) { yield head.value; } } 
+1
source

Source: https://habr.com/ru/post/1264326/