我是软件领域的新手。我有一个json数组对象,如
var treeObj = [
{
"name": "sriram",
"refernce_id": "SAN001",
"sponer_id": "SAN000"
},
{
"name": "neeraja",
"refernce_id": "SAN002",
"sponer_id": "SAN001"
},
{
"name": "upender",
"refernce_id": "SAN003",
"sponer_id": "SAN001"
},
{
"name": "manoj",
"refernce_id": "SAN004",
"sponer_id": "SAN002"
},
{
"name": "shirisha",
"refernce_id": "SAN005",
"sponer_id": "SAN002"
},
{
"name": "ragu",
"refernce_id": "SAN006",
"sponer_id": "SAN003"
},
{
"name": "santhu",
"refernce_id": "SAN007",
"sponer_id": "SAN003"
}
];
这里我将上面的对象传递给一个函数。在该函数中我需要在每个对象中比较引用id和sponer_id,如果它们相等,我们需要将它们推入一个我们称之为子对象的数组,就像下面一样,我们需要在子数组中检查引用id in存在于上面对象的sponer_id中,如果它再次出现,我们需要将它们推送到包含reference_id的对象的子数组中。最终的数组对象看起来像。
[
{
"name": "sriram",
"parent": null,
"children": [
{
"name": "neeraja",
"parent": "sriram",
"children": [
{
"name": "manoj",
"parent": "neeraja"
},
{
"name": "shirisha",
"parent": "neeraja"
}
]
},
{
"name": "upender",
"parent": "sriram",
"children": [
{
"name": "ragu",
"parent": "neeraja"
},
{
"name": "santhu",
"parent": "neeraja"
}
]
}
]
}
]
这里sriram的treeObj的引用id在neeraja和upender对象中作为sponer id出现。所以neeraja和upender成为sriram的孩子。和neeraja的reference_id在treeObj的manoj和shirisha对象中作为sponer_id出现。同时,子可以有更多的子对象,我们需要动态格式化对象。
我写的功能看起来像
var mainArr = [], subArrs = [], subObj={}, subIds = [], find = "SAN001";
formatData(treeObj);
function formatData(treeObj){debugger;
var arr = [];
for(var x=0; x<= treeObj.length-1; x++){debugger;
var sampData = treeObj[x];
if(find == sampData.sponer_id){
arr.push(sampData.refernce_id);
subArrs.push(sampData);
}
}
subIds.push(arr);
console.log(subIds);
console.log(subArrs);
formatData(subArrs);
}
请指导我哪里出错了。提前谢谢。
答案 0 :(得分:0)
//1. find all items the have no parent and push them on a stack like so:
let stack = treeObj.reduce((list, item) => {
if (<ids match>) list.push(item);
return item;
}, []),
let result = [].concat(stack);
//2. while loop the stack:
while (stack.length > 0) {
let item = stack.shift();
item.children = treeObj.reduce((list, child) => {
if (<ids match>) {
list.push(child);
}
return list;
}, []).map(child => {
child.parent = item;
stack.unshift(item);
return child;
});
}
return result;
<强>更新强>
所以在“好老JS”中有一些改进:
var stack = treeObj.filter(function (item) {
return item.<parent_id> === item.<child_id> });
var result = [].concat(stack);
while (stack.length > 0) {
var item = stack.shift();
item.children = treeObj.filter(function (child) {
return item.<id> === child.<parent_id>;
});
item.children.forEach(function (child) { stack.unshift(child) });
}
基本上:
while.length > 0
shift()
堆栈中的第一项unshift
完成
可以在循环中完成向项添加父属性或删除不需要的属性。整个事情也可以使用递归来完成,但我曾经通过做这样的事情来运行“太多的递归错误”,所以我更喜欢迭代方法。当然,代替.reduce
,.filter
和.forEach
,您可以使用常规循环,但我更喜欢功能样式。总而言之,无论你怎么做,都不是那么困难,只需要找到要素,然后再与所有孩子一起重复,等等。使用while
循环找到所有子项,或者将该元素作为root用于整个子树。
答案 1 :(得分:0)
您基本上是在尝试将数组转换为n-ary树。
将原始树函数输入formatData会为您提供一个数组(arr),其中所有对象的referenceID都是SAN001作为父对象,另一个数组(subArrs)包含所有子节点的sponberId SAN001。
然后将arr存储在subIds,log subIds和subArr中,并继续以递归方式调用subArrs上的格式数据。然后检查subArr哪些对象具有“SAN001作为前驱”(当时应该是所有对象)并在subArr中推送该对象。如果我没有弄错,这会导致无限循环。
改善的起点: 你的“发现”变量没有改变,它是硬连线到“SAN001” - 当你100%确定根对象总是有这个referenceID时,这对你的第一次旅行可能没问题。但是在第二次旅行中,您想要检查哪些对象依赖于第二级元素,因此您需要将find设置为相应的referenceId。
您的subArrs包含取决于SAN001的所有对象。但是在第二次和以后的旅行中,你不希望得到SAN001的孩子,而是subArr中的对象子。因此,您需要遍历在subArr中查找对象子节点的旧对象,而不是遍历寻找SAN001子节点的subArr。
希望清楚一点点。
进一步研究的暗示:你基本上试图用javascript“将数组转换为n-ary树”。