Javascript数组被填充,我不';我不明白怎么做
在搜索一个问题的解决方案时,我从邻接列表中找到了关于树结构的。我找到了一个答案,为我解决了这个问题,但我无法理解它是如何工作的,我觉得我缺少了一些关于javascript的基本理解 @TreyE in的答案给出了排序树的下一个解决方案->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,名称:“会计”,父项
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;i console.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个答案了。。。也许我做这件事有点太慢了