Javascript数组被填充,我不';我不明白怎么做

Javascript数组被填充,我不';我不明白怎么做,javascript,arrays,Javascript,Arrays,在搜索一个问题的解决方案时,我从邻接列表中找到了关于树结构的。我找到了一个答案,为我解决了这个问题,但我无法理解它是如何工作的,我觉得我缺少了一些关于javascript的基本理解 @TreyE in的答案给出了排序树的下一个解决方案-> var扁平=[ {id:1,名称:“业务”,父级:0}, {id:2,名称:“管理”,父项:1}, {id:3,姓名:“领导”,家长:2}, {id:4,姓名:“财务”,家长:1}, {id:5,名称:“虚构”,父项:0}, {id:6,名称:“会计”,父项

在搜索一个问题的解决方案时,我从邻接列表中找到了关于树结构的。我找到了一个答案,为我解决了这个问题,但我无法理解它是如何工作的,我觉得我缺少了一些关于javascript的基本理解

@TreyE in的答案给出了排序树的下一个解决方案->

var扁平=[
{id:1,名称:“业务”,父级:0},
{id:2,名称:“管理”,父项:1},
{id:3,姓名:“领导”,家长:2},
{id:4,姓名:“财务”,家长:1},
{id:5,名称:“虚构”,父项:0},
{id:6,名称:“会计”,父项:1},
{id:7,名称:“项目管理”,父项:2}
];
var节点=[];
var toplevelNodes=[];
var lookupList={};
对于(变量i=0;iconsole.log(toplevelNodes)也许另一种方法更容易理解?这将在适当位置修改
节点
(née
平面
),但:

/**
  Augment each node in the "nodes" list with a `children` property,
  and return the top-level nodes.
*/
function treeify(nodes) {
  const children = {};

  // Walk through the flat list of nodes once...
  nodes.forEach((n) => {
    // Retrieve or initialize a list for `n.parent`'s children.
    const childList = children[n.parent] || (children[n.parent] = []);
    // Add this node there.
    childList.push(n);
  });

  // ... and walk through it again, to assign the new `children` property.
  nodes.forEach((n) => {
    // Pick each "children" property from the children map,
    // or in case there is none, come up with an empty list.
    n.children = children[n.id] || [];
  });

  // Nodes with parent 0 are top-level; return them.
  return children[0];
}

const nodes = [
  { id: 1, name: "Business", parent: 0 },
  { id: 2, name: "Management", parent: 1 },
  { id: 3, name: "Leadership", parent: 2 },
  { id: 4, name: "Finance", parent: 1 },
  { id: 5, name: "Fiction", parent: 0 },
  { id: 6, name: "Accounting", parent: 1 },
  { id: 7, name: "Project Management", parent: 2 },
];

const tree = treeify(nodes);

// Node.js specific printing stuff...
const util = require("util");
console.log(util.inspect(tree, null, { depth: 5 }));
这个输出

[
  {
    id: 1,
    name: 'Business',
    parent: 0,
    children: [
      {
        id: 2,
        name: 'Management',
        parent: 1,
        children: [
          { id: 3, name: 'Leadership', parent: 2, children: [] },
          {
            id: 7,
            name: 'Project Management',
            parent: 2,
            children: []
          }
        ]
      },
      { id: 4, name: 'Finance', parent: 1, children: [] },
      { id: 6, name: 'Accounting', parent: 1, children: [] }
    ]
  },
  { id: 5, name: 'Fiction', parent: 0, children: [] }
]

也许另一种方法更容易理解?这将在适当位置修改
节点
(née
平面
),但:

/**
  Augment each node in the "nodes" list with a `children` property,
  and return the top-level nodes.
*/
function treeify(nodes) {
  const children = {};

  // Walk through the flat list of nodes once...
  nodes.forEach((n) => {
    // Retrieve or initialize a list for `n.parent`'s children.
    const childList = children[n.parent] || (children[n.parent] = []);
    // Add this node there.
    childList.push(n);
  });

  // ... and walk through it again, to assign the new `children` property.
  nodes.forEach((n) => {
    // Pick each "children" property from the children map,
    // or in case there is none, come up with an empty list.
    n.children = children[n.id] || [];
  });

  // Nodes with parent 0 are top-level; return them.
  return children[0];
}

const nodes = [
  { id: 1, name: "Business", parent: 0 },
  { id: 2, name: "Management", parent: 1 },
  { id: 3, name: "Leadership", parent: 2 },
  { id: 4, name: "Finance", parent: 1 },
  { id: 5, name: "Fiction", parent: 0 },
  { id: 6, name: "Accounting", parent: 1 },
  { id: 7, name: "Project Management", parent: 2 },
];

const tree = treeify(nodes);

// Node.js specific printing stuff...
const util = require("util");
console.log(util.inspect(tree, null, { depth: 5 }));
这个输出

[
  {
    id: 1,
    name: 'Business',
    parent: 0,
    children: [
      {
        id: 2,
        name: 'Management',
        parent: 1,
        children: [
          { id: 3, name: 'Leadership', parent: 2, children: [] },
          {
            id: 7,
            name: 'Project Management',
            parent: 2,
            children: []
          }
        ]
      },
      { id: 4, name: 'Finance', parent: 1, children: [] },
      { id: 6, name: 'Accounting', parent: 1, children: [] }
    ]
  },
  { id: 5, name: 'Fiction', parent: 0, children: [] }
]

lookupList将id映射到它们的节点,因为这是在第一个循环中添加到它的内容:
lookupList[n.id]=n


在第二个循环中,不是顶级节点的每个节点都将添加到其父节点的子节点数组中。在lookupList(
lookupList[n.parent\u id]
)中查找节点的parent\u id属性时检索其父节点。

lookupList将id映射到其节点,因为这是在第一个循环中添加到它的内容:
lookupList[n.id]=n


在第二个循环中,不是顶级节点的每个节点都将添加到其父节点的子节点数组中。在lookupList(
lookupList[n.parent\u id]
)中查找节点的parent\u id属性可检索其父节点。

秘密在于
lookupList
,它是一个。存储在该对象中的项(或活动项)不是深度克隆,它们只是指向内存中现有项的“指针”(不像C中那样精确指向内存地址),作为参考。如果节点发生更改(即:通过向节点添加更多子节点),对该元素的“引用”也将被修改,因为它实际上是同一节点

就在这里:

for (var i = 0; i < nodes.length; i++) {
  var n = nodes[i];
  if (!(n.parent_id == null)) {
      lookupList[n.parent_id].children = lookupList[n.parent_id].children.concat([n]);
  }
}

秘密在于
lookupList
,它是一个。存储在该对象中的项(或活动项)不是深度克隆,它们只是指向内存中现有项的“指针”(不像C中那样精确指向内存地址),作为参考。如果节点发生更改(即:通过向节点添加更多子节点),对该元素的“引用”也将被修改,因为它实际上是同一节点

就在这里:

for (var i = 0; i < nodes.length; i++) {
  var n = nodes[i];
  if (!(n.parent_id == null)) {
      lookupList[n.parent_id].children = lookupList[n.parent_id].children.concat([n]);
  }
}

在JS中,指向对象或数组的变量包含对该对象的引用,而不是该对象的副本

如果有多个变量指向同一对象,并通过一个变量对该对象进行变异,则另一个引用下的对象也会发生变异(因为两个变量都指向同一对象):

var a={hello:'a'}
var b=a
b、 你好='b'
console.log(a.hello)
//打印“b”
在代码中也会发生同样的情况:
节点
顶级节点
lookupList
都包含对它们内部相同节点对象的引用,当您在一个位置修改一个时,它也会在其他位置更新

基本上,这是一条神奇的路线:

lookupList[n.parent\u id]。children=。。。

如果您希望更深入地理解此主题,请查看此部分:

在JS变量中,指向对象或数组的变量包含对该对象的引用,而不是该对象的副本

如果有多个变量指向同一对象,并通过一个变量对该对象进行变异,则另一个引用下的对象也会发生变异(因为两个变量都指向同一对象):

var a={hello:'a'}
var b=a
b、 你好='b'
console.log(a.hello)
//打印“b”
在代码中也会发生同样的情况:
节点
顶级节点
lookupList
都包含对它们内部相同节点对象的引用,当您在一个位置修改一个时,它也会在其他位置更新

基本上,这是一条神奇的路线:

lookupList[n.parent\u id]。children=。。。

如果您希望更深入地理解此主题,请查看此部分:

在执行最后一个循环之前,
节点
顶级节点
都包含相同的对象
push
不会复制对象,
n
引用两个数组中的同一对象。我建议您使用
console.dir(variable)
查看数据,并尝试自己解决。在执行最后一个循环之前,
节点和
toplevelNodes
都包含相同的对象
push
不会复制对象,
n
在两个数组中引用同一个对象。我建议您使用
console.dir(变量)
查看数据,并尝试自己找出它。哇,键入一个答案后发现已经有3个答案可用。。。也许我有点太慢了…谢谢兄弟。很有帮助哇,输入完答案后意识到已经有3个答案了。。。也许我做这件事有点太慢了