根据Javascript中的节点号将平面列表数组转换为树状视图数组



我想根据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.

最新更新