我想根据Javascript中的节点号将平面列表数组转换为树状视图数组。节点编号表示子数组元素。例如节点号1.1表示元素"0"的子元素;A";节点号1.1.1表示元素"0"的子元素;B";等等
输入
[ { "name": "A", "nodeNumber": "1" }, { "name": "B", "nodeNumber": "1.1" }, { "name": "C", "nodeNumber": "1.1.1" }, { "name": "D", "nodeNumber": "1.2" }, { "name": "E", "nodeNumber": "1.2.1" }, { "name": "F", "nodeNumber": "1.2.2" } ]
预期输出
{ "name": "A", "nodeNumber": "1", "children" :[ { "name": "B", "nodeNumber": "1.1", "children" :[ { "name": "C", "nodeNumber": "1.1.1" } ] }, { "name": "D", "nodeNumber": "1.2", "children" :[ { "name": "E", "nodeNumber": "1.2.1" }, { "name": "F", "nodeNumber": "1.2.2" } ] } ] }
没有层次结构限制。
我试图将每个元素的唯一性作为关键,并尝试下一步,但我被困在了那里:
var res = [];
var flatList = [];
input.forEach(loopContent);
function loopContent(item,index,arr) {
let node = item.nodeNumber.split('.').join('_');
item['flat_id'] = node;
res[node] = item; flatList.push(node);
}
请帮我
了解可重用模块和相互递归的绝佳机会。这个答案中的这个解决方案解决了您的特定问题,而不需要对另一个答案中编写的模块进行任何修改。
在开始之前,我们必须首先提供一个针对您的问题的parent
函数。
const parent = (str = "") =>
{ const pos = str.lastIndexOf(".")
return pos === -1
? null
: str.substr(0, pos)
}
parent("1.2.2") // => "1.2"
parent("1.2") // => "1"
parent("1") // => null
现在让我们构建我们的树-
// Main.js
import { tree } from './Tree'
const input =
[ { name: "A", nodeNumber: "1" }, { name: "B", nodeNumber: "1.1" }, { name: "C", nodeNumber: "1.1.1" }, { name: "D", nodeNumber: "1.2" }, { name: "E", nodeNumber: "1.2.1" }, { name: "F", nodeNumber: "1.2.2" } ]
const result =
tree
( input // <- array of nodes
, node => parent(node.nodeNumber) // <- foreign key
, (node, children) => // <- node reconstructor function
({ ...node, children: children(node.nodeNumber) }) // <- primary key
)
console.log(JSON.stringify(result, null, 2))
输出-
[
{
"name": "A",
"nodeNumber": "1",
"children": [
{
"name": "B",
"nodeNumber": "1.1",
"children": [
{
"name": "C",
"nodeNumber": "1.1.1",
"children": []
}
]
},
{
"name": "D",
"nodeNumber": "1.2",
"children": [
{
"name": "E",
"nodeNumber": "1.2.1",
"children": []
},
{
"name": "F",
"nodeNumber": "1.2.2",
"children": []
}
]
}
]
}
]
就这样。为了完成这篇文章,我将附上Tree
模块的副本-
// Tree.js
import { index } from './Index'
const empty =
{}
function tree (all, indexer, maker, root = null)
{ const cache =
index(all, indexer)
const many = (all = []) =>
all.map(x => one(x))
// zero knowledge of forum object shape
const one = (single) =>
maker(single, next => many(cache.get(next)))
return many(cache.get(root))
}
export { empty, tree } // <-- public interface
以及Index
模块依赖性-
// Index.js
const empty = _ =>
new Map
const update = (r, k, t) =>
r.set(k, t(r.get(k)))
const append = (r, k, v) =>
update(r, k, (all = []) => [...all, v])
const index = (all = [], indexer) =>
all.reduce
( (r, v) => append(r, indexer(v), v) // zero knowledge of v shape
, empty()
)
export { empty, index, append } // <-- public interface
为了获得更多的见解,我鼓励你阅读最初的问答;A.