用于深度优先搜索的 Javascript 扩展运算符

标签 javascript ecmascript-6

我正在尝试使用扩展运算符 ... 将项目附加到深度优先搜索中的数组中。然而,它表现出奇怪的行为:

  • 使用array.push(),数组是正确的:['a','b','c','d];
  • 使用[...array, this.name],数组每次都不同。

例如:如果为这样的树递归调用 search() 函数:

   A
  /\
 B C
/
D

使用展开运算符,日志如下所示:

array = []
this.name = A
array = [A];
=====
array = [A]
this.name = B
array = [A,B]
=====
array = [A,B]
this.name = D
array = [A,B,D]
====
array = [A] // not [A,B,D]
this.name = C
array = [A,C]

使用push()日志如下所示:

array = []
this.name = A
array = [A];
=====
array = [A]
this.name = B
array = [A,B]
=====
array = [A,B]
this.name = D
array = [A,B,D]
====
array = [A,B,D]
this.name = C
array = [A,B,D,C] // expected
class Node {
    constructor(name) {
      this.name = name;
      this.children = [];
    }

    addChild(name) {
      this.children.push(new Node(name));
      return this;
    }

    search(array) {
        console.log('this name:');
        console.log(this.name);
        console.log('array before:');
        console.log(array);
        // array.push(this.name);
        array = [...array, this.name];
        console.log('array after');
        console.log(array);
        for (let child of this.children) {
            child.search(array);
        }
        return array;
    }
}

最佳答案

问题不在于您是否使用扩展运算符或 array.push() ,只是您的实现依赖于将搜索数组的同一实例传递给所有节点,但每次运行 array = [...array, this.name] 时您正在创建一个新数组实例,该实例现已与所有父搜索数组断开连接。

详细说明一下,array.push() 变异 array - 它仍然是相同的数组实例,只是具有新内容。但是array = [...] ,无论数组文字中有什么,都会创建一个包含新内容的新数组 - 对旧数组的引用,即传递给 search() 的数组。节点的父节点的函数将被丢弃。对 array 的所有进一步修改节点的父节点不会知道。

因为您需要在每个搜索函数中修改相同的数组实例,所以您只需使用 array.push()并且不传播,或传递包含 array 的对象到每个函数,以便每个分支的节点都可以访问相同的数组实例,无论它是否被重新分配。

关于用于深度优先搜索的 Javascript 扩展运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59146102/

相关文章:

javascript - 将真/假数组与其他数组进行比较

javascript - 如何在 Node.js 和 TestCafe 不等待检查选择器是否不存在的情况下编写 if 条件

javascript - 如何在 jquery droppable 事件中执行某些操作

javascript - 如何检查对象链中任何位置的 'undefined'?

javascript - window.console && console.log 是什么?

javascript - 在同一日期返回的多条记录按电话号码升序排序

javascript - JSX 生成 div 并推送到数组

phantomjs - 如何在 PhantomJS 中使用 ES6

javascript - 从函数访问兄弟对象

javascript - 将垂直滚动位置绑定(bind)到计​​数器