const result = [];
let remainIndex = [];
const res = [
{
traceInfo: {
node4: {
traceId: "F"
},
node5: {
traceId: "G"
}
},
name: "FG"
},
{
traceInfo: {
node4: {
traceId: "B"
},
node5: {
traceId: "D"
}
},
name: "BD"
},
{
traceInfo: {
node4: {
traceId: "B"
},
node5: {
traceId: "C"
}
},
name: "BC"
},
{
nodeId: "C-E",
traceInfo: {
node4: {
traceId: "C"
},
node5: {
traceId: "E"
}
},
name: "CE"
},
{
traceInfo: {
node4: {
traceId: "A"
},
node5: {
traceId: "B"
}
},
name: "AB"
},
{
traceInfo: {
node4: {
traceId: "E"
},
node5: {
traceId: "F"
}
},
name: "EF"
},
{
traceInfo: {
node4: {
traceId: "A"
},
node5: {
traceId: "A"
}
},
name: "AA"
}
];
function findRoot(res) {
res.forEach((row, index) => {
if (row.traceInfo.node4.traceId === row.traceInfo.node5.traceId) {
// root
result.push({
name: row.traceInfo.node4.traceId,
children: []
});
} else {
remainIndex.push(index);
}
});
}
function processItems(res) {
let remainIndexNext = [];
for (var i = 0; i < remainIndex.length; i++) {
let idx = remainIndex[i];
let parent = findParent(res[idx].traceInfo);
if (!parent) {
remainIndexNext.push(idx);
}
}
remainIndex = remainIndexNext;
}
function findParent(item) {
let parent = null;
for (var i = 0; i < result.length; i++) {
let row = result[i];
if (row.name === item.node4.traceId) {
row.children.push({
name: item.node5.traceId,
children: []
});
return row;
} else {
for (var j = 0; j < row.children.length; j++) {
let row2 = row.children[j];
if (row2.name === item.node4.traceId) {
row2.children.push({
name: item.node5.traceId,
children: []
});
return row2;
} else {
for (var k = 0; k < row2.children.length; k++) {
let row3 = row2.children[k];
if (row3.name === item.node4.traceId) {
row3.children.push({
name: item.node5.traceId,
children: []
});
return row3;
} else {
for (var l = 0; l < row3.children.length; l++) {
let row4 = row3.children[l];
if (row4.name === item.node4.traceId) {
row4.children.push({
name: item.node5.traceId,
children: []
});
return row4;
} else {
for (var n = 0; n < row4.children.length; n++) {
let row5 = row4.children[n];
if (row5.name === item.node4.traceId) {
row5.children.push({
name: item.node5.traceId,
children: []
});
return row5;
}
}
}
}
}
}
}
}
}
}
return parent;
}
findRoot(res);
while (remainIndex.length) {
processItems(res);
}
console.log(result);
有来自服务器API的响应数据,称为res。
如果node4和node5 traceId
的值相同,则它是结果的根。
node4.traceId
-node5.traceId
parent
-child
F-G
B-D
B-C
C-E
A-B
E-F
A-A
//result
A-B-C-E-F-G
-D
您可以在此处检查结果树形图。 https://codesandbox.io/s/10ovv8jvlj
由于要使用react-d3-tree,因此我必须格式化结果格式的数据。
我认为findParent
函数不是格式化的好方法。
有很多循环,如果服务器中的数据包含的数据多于当前res
的数据,则我必须添加更多的循环。
我想替换为递归函数,但我不知道。
如何更好地修改findParent
?
答案 0 :(得分:2)
findParent
比findChildren
更有意义,更容易编写递归。查找根目录->查找根目录的子项->查找根目录的每个子项-> ...
这是示例代码:
const res = [
{
traceInfo: {
node4: {
traceId: "F"
},
node5: {
traceId: "G"
}
},
name: "FG"
},
{
traceInfo: {
node4: {
traceId: "B"
},
node5: {
traceId: "D"
}
},
name: "BD"
},
{
traceInfo: {
node4: {
traceId: "B"
},
node5: {
traceId: "C"
}
},
name: "BC"
},
{
nodeId: "C-E",
traceInfo: {
node4: {
traceId: "C"
},
node5: {
traceId: "E"
}
},
name: "CE"
},
{
traceInfo: {
node4: {
traceId: "A"
},
node5: {
traceId: "B"
}
},
name: "AB"
},
{
traceInfo: {
node4: {
traceId: "E"
},
node5: {
traceId: "F"
}
},
name: "EF"
},
{
traceInfo: {
node4: {
traceId: "A"
},
node5: {
traceId: "A"
}
},
name: "AA"
}
];
function processRes(res)
{
var result = [];
for(let i = 0; i < res.length ; i++)
{
let info = res[i];
if(info.traceInfo.node4.traceId == info.traceInfo.node5.traceId)
{
let root = {name:info.traceInfo.node4.traceId,children:[]};
findChildren(res.slice(0,i).concat(res.slice(i+1)),root);
result.push(root);
}
}
return result;
}
function findChildren(res,parent)
{
for(let i = 0; i < res.length ; i++)
{
let info = res[i];
if(info.traceInfo.node4.traceId == parent.name && info.traceInfo.node4.traceId != info.traceInfo.node5.traceId)
{
let node = {name:info.traceInfo.node5.traceId,children:[]};
findChildren(res.slice(0,i).concat(res.slice(i+1)),node);
parent.children.push(node);
}
}
}
console.log(processRes(res));