如何理解javascript中将数组转换为Trearray的函数代码片段?
我有一个函数,可以将简单的对象数组转换为treeArray。这个函数不是我写的。该函数使用lodash u2;每个。它与本地forEach相同 下面是代码和示例数据:如何理解javascript中将数组转换为Trearray的函数代码片段?,javascript,arrays,reactjs,object,tree,Javascript,Arrays,Reactjs,Object,Tree,我有一个函数,可以将简单的对象数组转换为treeArray。这个函数不是我写的。该函数使用lodash u2;每个。它与本地forEach相同 下面是代码和示例数据: let a = [ { id: 1, name: "ADMINISTRATION" }, { id: 2, name: "ADMIN_GROUP", parentId: 1 }, { id: 3,
let a = [
{
id: 1,
name: "ADMINISTRATION"
},
{
id: 2,
name: "ADMIN_GROUP",
parentId: 1
},
{
id: 3,
name: "ADMIN_GROUP_CREATE",
parentId: 2
},
{
id:168,
name: "HELP_EDIT"
}
]
function makeTreeFromArray(list) {
const treeArray = [];
const treeMap = {};
_.each(list, (item, index) => {
treeMap[item.id] = index;
// list[index].children = [];
item.children = [];
});
_.each(list, item => {
if (item.parentId) {
list[treeMap[item.parentId]].children.push(item);
} else {
treeArray.push(item);
}
});
console.log('treeMap', treeMap);
console.log('list', list);
return treeArray;
}
const newArr = makeTreeFromArray(a);
console.log(newArr);
以下是输出:
我不理解这段代码:
...
_.each(list, item => {
if (item.parentId) {
list[treeMap[item.parentId]].children.push(item);
} else {
treeArray.push(item);
}
...
我获得两个对象的树阵列,但为什么有两个对象?我真的很累,很困惑。在这里,最初Trearray是空的。然后,仅当项目没有“parentId”时才推送该项目。如果它有“parentId”-则应用适当的逻辑。并将每个子对象推送到相应父对象的“子对象”属性。原来的名单发生了变异。但这里没有树耳环的“气味”。复杂父对象位于列表数组中。我说得对吗?但为什么最终,Trearray由两个对象组成,而不是一个?为什么复杂的父对象会神奇地出现在treeArray中?生成树的方法非常简单,但理想情况下,您需要理解JavaScript中的指针/引用才能理解它的工作原理。(它确实创建了很多指针/引用,还有其他方法可以使用更少的指针和可能更少的内存使用量来实现。此外,这只在平面列表已排序并且确实改变了原始列表的情况下才有效。还有其他方法可以从平面数组生成树,使用递归等,而不改变列表) 重要的是,原语(数字、布尔值等)存储在堆栈上,对象(如数组、对象等)存储在堆上。对象的变量只是指向堆上对象位置的指针。我不知道该推荐什么文章或YouTube视频,因为我读了/看了这么多不同的文章或视频- 根据您的示例,让我尝试逐行解释(代码中有注释):
a=[
{id:1,名称:“管理”},
{id:2,名称:“管理组”,父id:1},
{id:3,名称:“ADMIN\u GROUP\u CREATE”,parentId:2},
{id:168,名称:“HELP_EDIT”}
]
函数makeTreeFromArray(列表){
常量Trearray=[];
常量树映射={};
//此循环生成树映射
//并将.children道具添加到列表中的每个项目:
list.forEach((项目、索引)=>{
treeMap[item.id]=索引;
//列表[索引]。子项=[];
item.children=[];
});
//该函数的输出:
//它将ID映射到列表中的索引
/*
树映射={
"1": 0,
"2": 1,
"3": 2,
"168": 3
}
*/
//此循环将每个子级推送到原始列表中的父级(如果它有parentId)
//它使用treeMap(本质上是从id到索引的查找)来实现这一点。
//如果子级没有父级,则它是最高级别的父级
//在本例中,将其推送到输出树array(及其所有子项):
list.forEach(项=>{
if(item.parentId){
列表[treeMap[item.parentId].children.push(item);
}否则{
推拉(项目);
}
});
//log('treeMap',treeMap);
//console.log('list',list);
返回树耳道;
}
const newArr=makeTreeFromArray(a);
控制台日志(newArr)代码>这是一种非常简单的生成树的方法,但理想情况下,您需要了解JavaScript中的指针/引用才能了解它的工作原理。(它确实创建了很多指针/引用,还有其他方法可以使用更少的指针和可能更少的内存使用量来实现。此外,这只在平面列表已排序并且确实改变了原始列表的情况下才有效。还有其他方法可以从平面数组生成树,使用递归等,而不改变列表)
重要的是,原语(数字、布尔值等)存储在堆栈上,对象(如数组、对象等)存储在堆上。对象的变量只是指向堆上对象位置的指针。我不知道该推荐什么文章或YouTube视频,因为我读了/看了这么多不同的文章或视频-
根据您的示例,让我尝试逐行解释(代码中有注释):
a=[
{id:1,名称:“管理”},
{id:2,名称:“管理组”,父id:1},
{id:3,名称:“ADMIN\u GROUP\u CREATE”,parentId:2},
{id:168,名称:“HELP_EDIT”}
]
函数makeTreeFromArray(列表){
常量Trearray=[];
常量树映射={};
//此循环生成树映射
//并将.children道具添加到列表中的每个项目:
list.forEach((项目、索引)=>{
treeMap[item.id]=索引;
//列表[索引]。子项=[];
item.children=[];
});
//该函数的输出:
//它将ID映射到列表中的索引
/*
树映射={
"1": 0,
"2": 1,
"3": 2,
"168": 3
}
*/
//此循环将每个子级推送到原始列表中的父级(如果它有parentId)
//它使用treeMap(本质上是从id到索引的查找)来实现这一点。
//如果子级没有父级,则它是最高级别的父级
//在本例中,将其推送到输出树array(及其所有子项):
list.forEach(项=>{
if(item.parentId){
列表[treeMap[item.parentId].children.push(item);
}否则{
推拉(项目);
}
});
//log('treeMap',treeMap);
//console.log('list',list);
返回树耳道;
}
const newArr=makeTreeFromArray(a);
控制台日志(newArr)代码>
我获得两个对象的树阵列,但为什么有两个对象
您正确地标识了没有父ID的对象被追加到该数组中。输入数组中有两个这样的对象。因为它们没有对父对象的引用,所以它们应该被视为顶级对象,这就是为什么您应该在trearray
中只看到两个对象的原因。所有其他输入对象都应该在某些子属性的较深位置找到
如果它有“parentId”-适当的逻辑