1

I have a LinkedList class in Javascript(ES6) which has all the related helper methods (like insert, remove, update etc). Additionally, I want to implement a reusable forEach loop that can be used to iterate over the linked list.

class LinkedList(){
   constructor(){
      //linked list
      this.list = null; 
   }
   //Inserting a node at the first position
   insertFirst(data) {
      let node = new Node(data);
      if (this.list) {
        node.next = this.list;
        this.list = node;
      }
      else {
        this.list = node;
      }
    }
   //...
   //Other helper methods...
   //...

   forEach(){
      //loop implementation goes here
   }
}

//Node class for creating a new Node
class Node {
  constructor(data, next = null) {
    this.data = data;
    this.next = next;
  }
}

For instance, this is the linked list with 'n' nodes,

this.list = {
   data: 10,
   next: node1
};
let node1 = { 
   data: 20, 
   next: node2
};
let node2 = { 
   data: 20, 
   next: node3
};
So and so...

I should be able to iterate the list like an array forEach and perform any action at the node level, like below

const list = new LinkedList();

//inserted 10 nodes using list.insertFirst() method

list.forEach(node => { 
   console.log(node.data); 
});

What is the best possible way to achieve this?

nim007
  • 2,958
  • 3
  • 16
  • 28
  • I don't think `this.list` will actually reference `node1` properly as it is init after it. (https://stackoverflow.com/questions/33198849/what-is-the-temporal-dead-zone)? – evolutionxbox Oct 04 '20 at 19:29
  • you have omitted too much of the `LinkedList` class to provide any useful answer here. There are many ways to implement a Linked List; we might ***infer*** how you implemented yours based on your data, but without seeing the actual implementation, suggesting a way to iterate through would only be a **guess**. – Claies Oct 04 '20 at 19:31
  • I meant to show that, the first node has the reference of the second node like any linked list, not worried about the reference as this is a representation. – nim007 Oct 04 '20 at 19:31
  • 1
    Do you really create nodes as plain objects? Or do you have a Node class? In order for us to give a useful answer it is important we know these implementation details. – trincot Oct 04 '20 at 19:32
  • Yes, I will update the Node class too here. – nim007 Oct 04 '20 at 19:33

1 Answers1

4

I would define an iterator on the class. This way you can even iterate over the values with a for..of loop.

Then you can build the forEach method on top of that. But in many situations you'll find it easier to use the iterator instead of the forEach method, as you don't need to provide a callback function when using the iterator.

Here is how that could look:

class Node {
    constructor(data, next=null) {
        this.data = data;
        this.next = next;
    }
}

class LinkedList {
    constructor() {
        this.list = null; 
    }
    insertFirst(data) {
        this.list = new Node(data, this.list);
        return this; // add this line to make the method chainable!
    }
    * [Symbol.iterator]() { // define the default iterator for this class
        let node  = this.list; // get first node
        while (node) {  // while we have not reached the end of the list
            yield node.data;  // ... yield the current node's data
            node = node.next; // and move to the next node
        }
    }
    forEach(cb) { // Takes a callback argument.
        // As this object has a default iterator (see above) we
        //    can use the following syntax to consume that iterator.
        // Call the callback for each yielded value.
        for (let data of this) cb(data);
    }
}

let list = new LinkedList;
// Insert a few values. We makde the insertFirst method chainable:
list.insertFirst(30).insertFirst(20).insertFirst(10);
// Pass console.log as callback to call for each data in the list
list.forEach(console.log);
// ... or just with the iterator:
for (let data of list) console.log(data);
trincot
  • 317,000
  • 35
  • 244
  • 286
  • Thanks, Very useful implementation with the generator function. I have built the forEach loop on top of it. Would be helpful if you can add stepwise comments in the code. – nim007 Oct 04 '20 at 20:40
  • 1
    I added some comments. Let me know if something is unclear. – trincot Oct 04 '20 at 20:49