将数组转换为嵌套的 JSON 对象 - Angular Material 树
Convert array to nested JSON object - Angular Material tree
我拼命地尝试从 angular 树中以 JSON 嵌套格式获取选定的节点。到目前为止,我设法用 this.checklistSelection.selected
获得了选定的平面节点数组。但我需要的是,我需要以 JSON 格式获取选定的节点,所有嵌套的 JSON 对象按级别排列。
[{item: "Risk Analysis", level: 0, expandable: true}
,{item: "Standard", level: 1, expandable: true}
,{item: "Active", level: 2, expandable: true}
,{item: "Volatility", level: 3, expandable: true}
,{item: "Contribution", level: 4, expandable: true}
,{item: "Total", level: 5, expandable: false}
,{item: "Systematic", level: 5, expandable: false}
,{item: "Specific", level: 5, expandable: false}
,{item: "VaR (95%, 2 weeks, Chebyshev)", level: 3, expandable: true}
,{item: "Contribution", level: 4, expandable: true}
,{item: "Total", level: 5, expandable: false}
,{item: "Systematic", level: 5, expandable: false}
,{item: "Specific", level: 5, expandable: false}
,{item: "Benchmark", level: 2, expandable: true}
,{item: "Volatility", level: 3, expandable: true}
,{item: "Contribution", level: 4, expandable: true}
,{item: "Total", level: 5, expandable: false}
,{item: "Systematic", level: 5, expandable: false}
,{item: "Specific", level: 5, expandable: false}
,{item: "VaR (95%, 2 weeks, Chebyshev)", level: 3, expandable: true}
,{item: "Contribution", level: 4, expandable: true}
,{item: "Total", level: 5, expandable: false}
,{item: "Systematic", level: 5, expandable: false}
,{item: "Specific", level: 5, expandable: false}
,{item: "Portfolio", level: 2, expandable: true}
,{item: "Volatility", level: 3, expandable: true}
,{item: "Contribution", level: 4, expandable: true}
,{item: "Total", level: 5, expandable: false}
,{item: "Systematic", level: 5, expandable: false}
,{item: "Specific", level: 5, expandable: false}
,{item: "VaR (95%, 2 weeks, Chebyshev)", level: 3, expandable: true}
,{item: "Contribution", level: 4, expandable: true}
,{item: "Total", level: 5, expandable: false}
,{item: "Systematic", level: 5, expandable: false}
,{item: "Specific", level: 5, expandable: false}]
预计:
"Risk Analysis": {
"Standard": {
"Active": {
"Volatility": {
"Contribution": ["Total", "Systematic", "Specific"]
},
"VaR (95%, 2 weeks, Chebyshev)": {
"Contribution": ["Total", "Systematic", "Specific"]
}
},
"Portfolio": {
"Volatility": {
"Contribution": ["Total", "Systematic", "Specific"]
},
"VaR (95%, 2 weeks, Chebyshev)": {
"Contribution": ["Total", "Systematic", "Specific"]
}
},
"Benchmark": {
"Volatility": {
"Contribution": ["Total", "Systematic", "Specific"]
},
"VaR (95%, 2 weeks, Chebyshev)": {
"Contribution": ["Total", "Systematic", "Specific"]
}
}
}
}
}
如果有 Mat tree 提供的方法或任何类型的函数可以实现这种神奇效果,有人可以指出我吗?
提前致谢:)
为了构建树,您需要通过为每个项目分配 ID 来预处理数据。您可以使用堆栈来跟踪您分配的关系。
您可以分阶段完成:
- 为每个项目分配
id
和 parentId
键 (applyRelationships
)
- 将平面数组转换为树形数组(
listToTree
)
- 将树转换为对象(
treeToObject
)
在原来的例子中,我通过设置最大深度来强制嵌套每个对象。我没有使用 expandable
属性。在这个修改后的示例中,我放弃了 maxDepth
参数。
const main = () => {
useCases.forEach(({ data, expected }) => {
const actual = buildTreeObject(data);
console.log(JSON.stringify(actual) === JSON.stringify(expected));
console.log(actual);
});
};
const useCases = [{
data: [
{ item: "Risk Analysis", level: 0, expandable: true },
{ item: "Volatility", level: 1, expandable: true },
{ item: "Total", level: 2, expandable: false },
{ item: "Systematic", level: 2, expandable: false },
{ item: "Specific", level: 2, expandable: false },
{ item: "TaR (68%, 1 year)", level: 1, expandable: true },
{ item: "Total", level: 2, expandable: false },
{ item: "Systematic", level: 2, expandable: false },
{ item: "Specific", level: 2, expandable: false },
{ item: "VaR (95%, 2 weeks, Chebyshev)", level: 1, expandable: true },
{ item: "Total", level: 2, expandable: false },
{ item: "Systematic", level: 2, expandable: false },
{ item: "Specific", level: 2, expandable: false }
],
expected: {
"Risk Analysis": {
"Volatility": ["Total", "Systematic", "Specific"],
"TaR (68%, 1 year)": ["Total", "Systematic", "Specific"],
"VaR (95%, 2 weeks, Chebyshev)": ["Total", "Systematic", "Specific"]
}
}
}, {
data: [
{ item: "Risk Analysis", level: 0, expandable: true },
{ item: "Standard", level: 1, expandable: true },
{ item: "Active", level: 2, expandable: true },
{ item: "Volatility", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false }
],
expected: {
"Risk Analysis": {
"Standard": {
"Active": {
"Volatility": {
"Contribution": [ "Total", "Systematic", "Specific" ]
}
}
}
}
}
}, {
data: [
{ item: "Risk Analysis", level: 0, expandable: true },
{ item: "Standard", level: 1, expandable: true },
{ item: "Active", level: 2, expandable: true },
{ item: "Volatility", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false },
{ item: "VaR (95%, 2 weeks, Chebyshev)", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false },
{ item: "Benchmark", level: 2, expandable: true },
{ item: "Volatility", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false },
{ item: "VaR (95%, 2 weeks, Chebyshev)", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false },
{ item: "Portfolio", level: 2, expandable: true },
{ item: "Volatility", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false },
{ item: "VaR (95%, 2 weeks, Chebyshev)", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false }
],
expected: {
"Risk Analysis": {
"Standard": {
"Active": {
"Volatility": {
"Contribution": ["Total", "Systematic", "Specific"]
},
"VaR (95%, 2 weeks, Chebyshev)": {
"Contribution": ["Total", "Systematic", "Specific"]
}
},
"Benchmark": {
"Volatility": {
"Contribution": ["Total", "Systematic", "Specific"]
},
"VaR (95%, 2 weeks, Chebyshev)": {
"Contribution": ["Total", "Systematic", "Specific"]
}
},
"Portfolio": {
"Volatility": {
"Contribution": ["Total", "Systematic", "Specific"]
},
"VaR (95%, 2 weeks, Chebyshev)": {
"Contribution": ["Total", "Systematic", "Specific"]
}
},
}
}
}
}];
const applyRelationships = (data) => {
let levelStack = [], lastNode = null;
return data.map((curr, index) => {
const node = { ...curr, id: index + 1 };
if (levelStack.length === 0) {
levelStack.push({ level: node.level, parent: 0 });
} else {
const last = levelStack[levelStack.length - 1];
if (node.level > last.level) {
levelStack.push({ level: node.level, parent: lastNode.id });
} else if (node.level < last.level) {
const
levelDiff = last.level - node.level - 1,
lastIndex = levelStack.length - 1;
levelStack.splice(lastIndex - levelDiff, lastIndex);
}
}
node.parentId = levelStack[levelStack.length - 1].parent;
lastNode = node;
return node;
});
};
const listToTree = (arr = []) => {
let indexMap = new Map();
arr.forEach((node, index) => {
indexMap.set(node.id, index)
node.children = [];
});
return arr.reduce((res, node, index, all) => {
if (node.parentId === 0) return [...res, node];
all[indexMap.get(node.parentId)].children.push(node);
return res;
}, []);
};
const treeToObject = (tree = [], result = {}) => {
tree.forEach(child => {
if (!child.expandable) {
result.push(child.item);
} else {
const childrenAllEmpty = child.children
.every(({ children }) => children.length === 0);
result[child.item] = childrenAllEmpty ? [] : {};
treeToObject(child.children, result[child.item]);
}
});
return result;
};
const buildTreeObject = (arr = []) =>
treeToObject(listToTree(applyRelationships(arr)));
main();
.as-console-wrapper { top: 0; max-height: 100% !important; }
原始回复
const main = () => {
useCases.forEach(({ data, params: { maxDepth }, expected }) => {
const actual = buildTreeObject(data, maxDepth);
console.log(JSON.stringify(actual) === JSON.stringify(expected));
console.log(actual);
});
};
const useCases = [{
data: [
{ item: "Risk Analysis", level: 0, expandable: true },
{ item: "Volatility", level: 1, expandable: true },
{ item: "Total", level: 2, expandable: false },
{ item: "Systematic", level: 2, expandable: false },
{ item: "Specific", level: 2, expandable: false },
{ item: "TaR (68%, 1 year)", level: 1, expandable: true },
{ item: "Total", level: 2, expandable: false },
{ item: "Systematic", level: 2, expandable: false },
{ item: "Specific", level: 2, expandable: false },
{ item: "VaR (95%, 2 weeks, Chebyshev)", level: 1, expandable: true },
{ item: "Total", level: 2, expandable: false },
{ item: "Systematic", level: 2, expandable: false },
{ item: "Specific", level: 2, expandable: false }
],
params : { maxDepth: 1 },
expected: {
"Risk Analysis": {
"Volatility": ["Total", "Systematic", "Specific"],
"TaR (68%, 1 year)": ["Total", "Systematic", "Specific"],
"VaR (95%, 2 weeks, Chebyshev)": ["Total", "Systematic", "Specific"]
}
}
}, {
data: [
{ item: "Risk Analysis", level: 0, expandable: true },
{ item: "Standard", level: 1, expandable: true },
{ item: "Active", level: 2, expandable: true },
{ item: "Volatility", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false }
],
params: { maxDepth: 4 },
expected: {
"Risk Analysis": {
"Standard": {
"Active": {
"Volatility": {
"Contribution": [ "Total", "Systematic", "Specific" ]
}
}
}
}
}
}];
const applyRelationships = (data) => {
let levelStack = [], lastNode = null;
return data.map((curr, index) => {
const node = { ...curr, id: index + 1 };
if (levelStack.length === 0) {
levelStack.push({ level: node.level, parent: 0 });
} else {
const last = levelStack[levelStack.length - 1];
if (node.level > last.level) {
levelStack.push({ level: node.level, parent: lastNode.id });
} else if (node.level < last.level) {
levelStack.pop();
}
}
node.parentId = levelStack[levelStack.length - 1].parent;
lastNode = node;
return node;
});
};
const listToTree = (arr = []) => {
let indexMap = new Map();
arr.forEach((node, index) => {
indexMap.set(node.id, index)
node.children = [];
});
return arr.reduce((res, node, index, all) => {
if (node.parentId === 0) return [...res, node];
all[indexMap.get(node.parentId)].children.push(node);
return res;
}, []);
};
const treeToObject = (tree, maxDepth = 1, result = {}) => {
tree.forEach(child => {
result[child.item] = {};
if (child.level >= maxDepth) {
result[child.item] = child.children.map(({ item }) => item);
} else {
treeToObject(child.children, maxDepth, result[child.item]);
}
});
return result;
};
const buildTreeObject = (arr = [], maxDepth = 1) =>
treeToObject(listToTree(applyRelationships(arr)), maxDepth);
main();
.as-console-wrapper { top: 0; max-height: 100% !important; }
我拼命地尝试从 angular 树中以 JSON 嵌套格式获取选定的节点。到目前为止,我设法用 this.checklistSelection.selected
获得了选定的平面节点数组。但我需要的是,我需要以 JSON 格式获取选定的节点,所有嵌套的 JSON 对象按级别排列。
[{item: "Risk Analysis", level: 0, expandable: true}
,{item: "Standard", level: 1, expandable: true}
,{item: "Active", level: 2, expandable: true}
,{item: "Volatility", level: 3, expandable: true}
,{item: "Contribution", level: 4, expandable: true}
,{item: "Total", level: 5, expandable: false}
,{item: "Systematic", level: 5, expandable: false}
,{item: "Specific", level: 5, expandable: false}
,{item: "VaR (95%, 2 weeks, Chebyshev)", level: 3, expandable: true}
,{item: "Contribution", level: 4, expandable: true}
,{item: "Total", level: 5, expandable: false}
,{item: "Systematic", level: 5, expandable: false}
,{item: "Specific", level: 5, expandable: false}
,{item: "Benchmark", level: 2, expandable: true}
,{item: "Volatility", level: 3, expandable: true}
,{item: "Contribution", level: 4, expandable: true}
,{item: "Total", level: 5, expandable: false}
,{item: "Systematic", level: 5, expandable: false}
,{item: "Specific", level: 5, expandable: false}
,{item: "VaR (95%, 2 weeks, Chebyshev)", level: 3, expandable: true}
,{item: "Contribution", level: 4, expandable: true}
,{item: "Total", level: 5, expandable: false}
,{item: "Systematic", level: 5, expandable: false}
,{item: "Specific", level: 5, expandable: false}
,{item: "Portfolio", level: 2, expandable: true}
,{item: "Volatility", level: 3, expandable: true}
,{item: "Contribution", level: 4, expandable: true}
,{item: "Total", level: 5, expandable: false}
,{item: "Systematic", level: 5, expandable: false}
,{item: "Specific", level: 5, expandable: false}
,{item: "VaR (95%, 2 weeks, Chebyshev)", level: 3, expandable: true}
,{item: "Contribution", level: 4, expandable: true}
,{item: "Total", level: 5, expandable: false}
,{item: "Systematic", level: 5, expandable: false}
,{item: "Specific", level: 5, expandable: false}]
预计:
"Risk Analysis": {
"Standard": {
"Active": {
"Volatility": {
"Contribution": ["Total", "Systematic", "Specific"]
},
"VaR (95%, 2 weeks, Chebyshev)": {
"Contribution": ["Total", "Systematic", "Specific"]
}
},
"Portfolio": {
"Volatility": {
"Contribution": ["Total", "Systematic", "Specific"]
},
"VaR (95%, 2 weeks, Chebyshev)": {
"Contribution": ["Total", "Systematic", "Specific"]
}
},
"Benchmark": {
"Volatility": {
"Contribution": ["Total", "Systematic", "Specific"]
},
"VaR (95%, 2 weeks, Chebyshev)": {
"Contribution": ["Total", "Systematic", "Specific"]
}
}
}
}
}
如果有 Mat tree 提供的方法或任何类型的函数可以实现这种神奇效果,有人可以指出我吗?
提前致谢:)
为了构建树,您需要通过为每个项目分配 ID 来预处理数据。您可以使用堆栈来跟踪您分配的关系。
您可以分阶段完成:
- 为每个项目分配
id
和parentId
键 (applyRelationships
) - 将平面数组转换为树形数组(
listToTree
) - 将树转换为对象(
treeToObject
)
在原来的例子中,我通过设置最大深度来强制嵌套每个对象。我没有使用 expandable
属性。在这个修改后的示例中,我放弃了 maxDepth
参数。
const main = () => {
useCases.forEach(({ data, expected }) => {
const actual = buildTreeObject(data);
console.log(JSON.stringify(actual) === JSON.stringify(expected));
console.log(actual);
});
};
const useCases = [{
data: [
{ item: "Risk Analysis", level: 0, expandable: true },
{ item: "Volatility", level: 1, expandable: true },
{ item: "Total", level: 2, expandable: false },
{ item: "Systematic", level: 2, expandable: false },
{ item: "Specific", level: 2, expandable: false },
{ item: "TaR (68%, 1 year)", level: 1, expandable: true },
{ item: "Total", level: 2, expandable: false },
{ item: "Systematic", level: 2, expandable: false },
{ item: "Specific", level: 2, expandable: false },
{ item: "VaR (95%, 2 weeks, Chebyshev)", level: 1, expandable: true },
{ item: "Total", level: 2, expandable: false },
{ item: "Systematic", level: 2, expandable: false },
{ item: "Specific", level: 2, expandable: false }
],
expected: {
"Risk Analysis": {
"Volatility": ["Total", "Systematic", "Specific"],
"TaR (68%, 1 year)": ["Total", "Systematic", "Specific"],
"VaR (95%, 2 weeks, Chebyshev)": ["Total", "Systematic", "Specific"]
}
}
}, {
data: [
{ item: "Risk Analysis", level: 0, expandable: true },
{ item: "Standard", level: 1, expandable: true },
{ item: "Active", level: 2, expandable: true },
{ item: "Volatility", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false }
],
expected: {
"Risk Analysis": {
"Standard": {
"Active": {
"Volatility": {
"Contribution": [ "Total", "Systematic", "Specific" ]
}
}
}
}
}
}, {
data: [
{ item: "Risk Analysis", level: 0, expandable: true },
{ item: "Standard", level: 1, expandable: true },
{ item: "Active", level: 2, expandable: true },
{ item: "Volatility", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false },
{ item: "VaR (95%, 2 weeks, Chebyshev)", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false },
{ item: "Benchmark", level: 2, expandable: true },
{ item: "Volatility", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false },
{ item: "VaR (95%, 2 weeks, Chebyshev)", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false },
{ item: "Portfolio", level: 2, expandable: true },
{ item: "Volatility", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false },
{ item: "VaR (95%, 2 weeks, Chebyshev)", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false }
],
expected: {
"Risk Analysis": {
"Standard": {
"Active": {
"Volatility": {
"Contribution": ["Total", "Systematic", "Specific"]
},
"VaR (95%, 2 weeks, Chebyshev)": {
"Contribution": ["Total", "Systematic", "Specific"]
}
},
"Benchmark": {
"Volatility": {
"Contribution": ["Total", "Systematic", "Specific"]
},
"VaR (95%, 2 weeks, Chebyshev)": {
"Contribution": ["Total", "Systematic", "Specific"]
}
},
"Portfolio": {
"Volatility": {
"Contribution": ["Total", "Systematic", "Specific"]
},
"VaR (95%, 2 weeks, Chebyshev)": {
"Contribution": ["Total", "Systematic", "Specific"]
}
},
}
}
}
}];
const applyRelationships = (data) => {
let levelStack = [], lastNode = null;
return data.map((curr, index) => {
const node = { ...curr, id: index + 1 };
if (levelStack.length === 0) {
levelStack.push({ level: node.level, parent: 0 });
} else {
const last = levelStack[levelStack.length - 1];
if (node.level > last.level) {
levelStack.push({ level: node.level, parent: lastNode.id });
} else if (node.level < last.level) {
const
levelDiff = last.level - node.level - 1,
lastIndex = levelStack.length - 1;
levelStack.splice(lastIndex - levelDiff, lastIndex);
}
}
node.parentId = levelStack[levelStack.length - 1].parent;
lastNode = node;
return node;
});
};
const listToTree = (arr = []) => {
let indexMap = new Map();
arr.forEach((node, index) => {
indexMap.set(node.id, index)
node.children = [];
});
return arr.reduce((res, node, index, all) => {
if (node.parentId === 0) return [...res, node];
all[indexMap.get(node.parentId)].children.push(node);
return res;
}, []);
};
const treeToObject = (tree = [], result = {}) => {
tree.forEach(child => {
if (!child.expandable) {
result.push(child.item);
} else {
const childrenAllEmpty = child.children
.every(({ children }) => children.length === 0);
result[child.item] = childrenAllEmpty ? [] : {};
treeToObject(child.children, result[child.item]);
}
});
return result;
};
const buildTreeObject = (arr = []) =>
treeToObject(listToTree(applyRelationships(arr)));
main();
.as-console-wrapper { top: 0; max-height: 100% !important; }
原始回复
const main = () => {
useCases.forEach(({ data, params: { maxDepth }, expected }) => {
const actual = buildTreeObject(data, maxDepth);
console.log(JSON.stringify(actual) === JSON.stringify(expected));
console.log(actual);
});
};
const useCases = [{
data: [
{ item: "Risk Analysis", level: 0, expandable: true },
{ item: "Volatility", level: 1, expandable: true },
{ item: "Total", level: 2, expandable: false },
{ item: "Systematic", level: 2, expandable: false },
{ item: "Specific", level: 2, expandable: false },
{ item: "TaR (68%, 1 year)", level: 1, expandable: true },
{ item: "Total", level: 2, expandable: false },
{ item: "Systematic", level: 2, expandable: false },
{ item: "Specific", level: 2, expandable: false },
{ item: "VaR (95%, 2 weeks, Chebyshev)", level: 1, expandable: true },
{ item: "Total", level: 2, expandable: false },
{ item: "Systematic", level: 2, expandable: false },
{ item: "Specific", level: 2, expandable: false }
],
params : { maxDepth: 1 },
expected: {
"Risk Analysis": {
"Volatility": ["Total", "Systematic", "Specific"],
"TaR (68%, 1 year)": ["Total", "Systematic", "Specific"],
"VaR (95%, 2 weeks, Chebyshev)": ["Total", "Systematic", "Specific"]
}
}
}, {
data: [
{ item: "Risk Analysis", level: 0, expandable: true },
{ item: "Standard", level: 1, expandable: true },
{ item: "Active", level: 2, expandable: true },
{ item: "Volatility", level: 3, expandable: true },
{ item: "Contribution", level: 4, expandable: true },
{ item: "Total", level: 5, expandable: false },
{ item: "Systematic", level: 5, expandable: false },
{ item: "Specific", level: 5, expandable: false }
],
params: { maxDepth: 4 },
expected: {
"Risk Analysis": {
"Standard": {
"Active": {
"Volatility": {
"Contribution": [ "Total", "Systematic", "Specific" ]
}
}
}
}
}
}];
const applyRelationships = (data) => {
let levelStack = [], lastNode = null;
return data.map((curr, index) => {
const node = { ...curr, id: index + 1 };
if (levelStack.length === 0) {
levelStack.push({ level: node.level, parent: 0 });
} else {
const last = levelStack[levelStack.length - 1];
if (node.level > last.level) {
levelStack.push({ level: node.level, parent: lastNode.id });
} else if (node.level < last.level) {
levelStack.pop();
}
}
node.parentId = levelStack[levelStack.length - 1].parent;
lastNode = node;
return node;
});
};
const listToTree = (arr = []) => {
let indexMap = new Map();
arr.forEach((node, index) => {
indexMap.set(node.id, index)
node.children = [];
});
return arr.reduce((res, node, index, all) => {
if (node.parentId === 0) return [...res, node];
all[indexMap.get(node.parentId)].children.push(node);
return res;
}, []);
};
const treeToObject = (tree, maxDepth = 1, result = {}) => {
tree.forEach(child => {
result[child.item] = {};
if (child.level >= maxDepth) {
result[child.item] = child.children.map(({ item }) => item);
} else {
treeToObject(child.children, maxDepth, result[child.item]);
}
});
return result;
};
const buildTreeObject = (arr = [], maxDepth = 1) =>
treeToObject(listToTree(applyRelationships(arr)), maxDepth);
main();
.as-console-wrapper { top: 0; max-height: 100% !important; }