如何为javascript链表实现forEach循环

如何为javascript链表实现forEach循环,javascript,data-structures,ecmascript-6,linked-list,Javascript,Data Structures,Ecmascript 6,Linked List,我有一个Javascript(ES6)中的LinkedList类,它有所有相关的助手方法(如插入、删除、更新等)。此外,我还想实现一个可重用的forEach循环,该循环可用于遍历链表 class LinkedList(){ constructor(){ //linked list this.list = null; } //Inserting a node at the first position insertFirst(data) {

我有一个Javascript(ES6)中的LinkedList类,它有所有相关的助手方法(如插入、删除、更新等)。此外,我还想实现一个可重用的forEach循环,该循环可用于遍历链表

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;
  }
}
例如,这是具有“n”个节点的链表

this.list = {
   data: 10,
   next: node1
};
let node1 = { 
   data: 20, 
   next: node2
};
let node2 = { 
   data: 20, 
   next: node3
};
So and so...
我应该能够像forEach数组一样迭代列表,并在节点级别执行任何操作,如下所示

const list = new LinkedList();

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

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

实现这一点的最佳方法是什么?

我将在类上定义一个迭代器。这样,您甚至可以使用
for..of
循环对值进行迭代

然后,您可以在此基础上构建
forEach
方法。但是在许多情况下,您会发现使用迭代器比使用
forEach
方法更容易,因为使用迭代器时不需要提供回调函数

下面是它的样子:

类节点{
构造函数(数据,next=null){
这个数据=数据;
this.next=next;
}
}
类链接列表{
构造函数(){
this.list=null;
}
insertFirst(数据){
this.list=新节点(数据,this.list);
返回此;//添加此行以使方法可链接!
}
*[Symbol.iterator](){//定义此类的默认迭代器
let node=this.list;//获取第一个节点
while(node){//while我们还没有到达列表的末尾
yield node.data;/…生成当前节点的数据
node=node.next;//并移动到下一个节点
}
}
forEach(cb){//接受回调参数。
//由于这个对象有一个默认迭代器(见上文),我们
//可以使用以下语法使用该迭代器。
//为每个生成的值调用回调。
对于(本文件的数据)cb(数据);
}
}
let list=新链接列表;
//插入一些值。我们使insertFirst方法可链接:
insertFirst(30)、insertFirst(20)、insertFirst(10);
//将console.log作为回调传递,以调用列表中的每个数据
list.forEach(console.log);
// ... 或者只使用迭代器:

for(让列表的数据)console.log(数据)我将在类上定义一个迭代器。这样,您甚至可以使用
for..of
循环对值进行迭代

然后,您可以在此基础上构建
forEach
方法。但是在许多情况下,您会发现使用迭代器比使用
forEach
方法更容易,因为使用迭代器时不需要提供回调函数

下面是它的样子:

类节点{
构造函数(数据,next=null){
这个数据=数据;
this.next=next;
}
}
类链接列表{
构造函数(){
this.list=null;
}
insertFirst(数据){
this.list=新节点(数据,this.list);
返回此;//添加此行以使方法可链接!
}
*[Symbol.iterator](){//定义此类的默认迭代器
let node=this.list;//获取第一个节点
while(node){//while我们还没有到达列表的末尾
yield node.data;/…生成当前节点的数据
node=node.next;//并移动到下一个节点
}
}
forEach(cb){//接受回调参数。
//由于这个对象有一个默认迭代器(见上文),我们
//可以使用以下语法使用该迭代器。
//为每个生成的值调用回调。
对于(本文件的数据)cb(数据);
}
}
let list=新链接列表;
//插入一些值。我们使insertFirst方法可链接:
insertFirst(30)、insertFirst(20)、insertFirst(10);
//将console.log作为回调传递,以调用列表中的每个数据
list.forEach(console.log);
// ... 或者只使用迭代器:

for(让列表的数据)console.log(数据)
我不认为
这个.list
会正确地引用
节点1
,因为它后面是init。()?您省略了太多的
LinkedList
类,无法在此提供任何有用的答案。有很多方法可以实现链表;我们可能会根据您的数据推断出您是如何实现的,但在没有看到实际实现的情况下,建议一种迭代方式只是一种猜测。我的意思是,第一个节点与任何链表一样,都有第二个节点的引用,不用担心引用,因为这是一种表示。您真的将节点创建为普通对象吗?或者你有一个节点类?为了给我们一个有用的答案,我们知道这些实现细节是很重要的。是的,我也会在这里更新节点类。我不认为
this.list
会正确地引用
node1
,因为它后面是init。()?您省略了太多的
LinkedList
类,无法在此提供任何有用的答案。有很多方法可以实现链表;我们可能会根据您的数据推断出您是如何实现的,但在没有看到实际实现的情况下,建议一种迭代方式只是一种猜测。我的意思是,第一个节点与任何链表一样,都有第二个节点的引用,不用担心引用,因为这是一种表示。您真的将节点创建为普通对象吗?或者你有一个节点类?为了给我们一个有用的答案,我们必须了解这些实现细节。是的,我也将在这里更新节点类。谢谢,非常有用的生成器函数实现。我已经在上面构建了forEach循环。如果你能在代码中添加分步注释会很有帮助。我添加了一些注释。如果有不清楚的地方,请告诉我。谢谢,这是一个非常有用的生成器函数实现。我已经在上面构建了forEach循环。如果你能在代码中添加分步注释会很有帮助。我添加了一些注释。让我知道