javascript - JavaScript 将树转换为嵌套数组
问题描述
我有一个使用 jquery 流程图库的流程图输入,如下所示:
我得到这样的数据表示:
{
"operators": {
"0": {
"properties": {
"title": "Start",
"inputs": {},
"outputs": {
"outs": {
"label": "Output (:i)",
"multiple": true
}
},
"class": "start-operator"
},
"top": 0,
"left": 0
},
"1": {
"properties": {
"title": "End",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {},
"class": "end-operator"
},
"top": null,
"left": null
},
"37": {
"properties": {
"title": "CHROM",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 300,
"top": 0
},
"38": {
"properties": {
"title": "CHROM",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 580,
"top": 0
},
"39": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 920,
"top": 0
},
"40": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 300,
"top": 100
},
"41": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 300,
"top": 200
},
"42": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 620,
"top": 140
},
"43": {
"properties": {
"title": "POS",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 740,
"top": 320
}
},
"links": {
"0": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 0,
"toOperator": 37,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #e53935"
},
"1": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 1,
"toOperator": 40,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #d81b60"
},
"2": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 2,
"toOperator": 41,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #8e24aa"
},
"3": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 3,
"toOperator": 43,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #5e35b1"
},
"4": {
"fromOperator": 37,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 38,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #3949ab"
},
"5": {
"fromOperator": 40,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 42,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #546e7a"
},
"6": {
"fromOperator": 41,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 42,
"toConnector": "ins",
"toSubConnector": 1,
"color": " #039be5"
},
"7": {
"fromOperator": 38,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 39,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #00acc1"
},
"8": {
"fromOperator": 42,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 39,
"toConnector": "ins",
"toSubConnector": 1,
"color": " #00897b"
},
"9": {
"fromOperator": 39,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": "1",
"toConnector": "ins",
"toSubConnector": 0,
"color": " #43a047"
},
"10": {
"fromOperator": 43,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": "1",
"toConnector": "ins",
"toSubConnector": 1,
"color": " #7cb342"
}
},
"operatorTypes": {}
}
我想用它来过滤制表器中的数据,所以把它变成这样:
[
{
"id": 1,
"pid": null
},
{
"id": 39,
"pid": 1
},
{
"id": 38,
"pid": 39
},
{
"id": 37,
"pid": 38
},
{
"id": 42,
"pid": 39
},
{
"id": 40,
"pid": 42
},
{
"id": 41,
"pid": 42
},
{
"id": 43,
"pid": 1
}
]
然后使用这条线我变成了一棵树:
const idMapping = data.reduce((acc, el, i) => {
acc[el.id] = i;
return acc;
}, {});
let root;
data.forEach(el => {
// Handle the root element
if (el.pid === null) {
root = el;
return;
}
// Use our mapping to locate the parent element in our data array
const parentEl = data[idMapping[el.pid]];
// Add our current el to its parent's `children` array
parentEl.children = [...(parentEl.children || []), el];
});
这是一棵树:
{
"id": 1,
"pid": null,
"children": [
{
"id": 39,
"pid": 1,
"children": [
{
"id": 38,
"pid": 39,
"children": [
{
"id": 37,
"pid": 38
}
]
},
{
"id": 42,
"pid": 39,
"children": [
{
"id": 40,
"pid": 42
},
{
"id": 41,
"pid": 42
}
]
}
]
},
{
"id": 43,
"pid": 1
}
]
}
然而,我想进一步简化这个只是嵌套的 id 数组。像这样:
[
1,
[
[
39,
[
[
38,
[
37
],
],
[
42,
[
40,
41
]
]
]
],
43
]
]
问题是,如何从树转换为嵌套数组?
解决方案
您可以使用递归来执行此操作;叶 id 向上传递而没有数组包装器,而内部节点 id 被包装在一个数组中,并为其子元素提供第二个元素。
const tree = { "id": 1, "pid": null, "children": [ { "id": 39, "pid": 1, "children": [ { "id": 38, "pid": 39, "children": [ { "id": 37, "pid": 38 } ] }, { "id": 42, "pid": 39, "children": [ { "id": 40, "pid": 42 }, { "id": 41, "pid": 42 } ] } ] }, { "id": 43, "pid": 1 } ] };
const objTreeToArrTree = node =>
node.children
? [node.id].concat([node.children.map(objTreeToArrTree)])
: node.id
;
console.log(JSON.stringify(objTreeToArrTree(tree), null, 2));
推荐阅读
- windows - std::thread 增加 DLL 引用计数?如何?
- apache - 无法在 CentOS 7 上的 Apache 中更改域名
- mysql - sqlalchemy 连接丢失的有限循环中的 MYSQL 查询
- reactjs - 删除 redux 状态的项目在 Firefox 中有效,但在 Chrome 中无效
- javascript - 如何搜索 API
- c# - WCF / MSMQ / 权限 / Windows 10 & VS2019
- python - 试图制作一个简单的 python web 服务器并且它没有启动
- python - 在 rPi3B+ 上使用 100% CPU 的简单 python 脚本
- powerbi - 小计不反映基础行计算的总和
- r - 获取从 R 调用的 Matlab 中脚本的输出