了解可重用module和相互递归的绝佳机会。此答案中的此解决方案解决了您的特定问题,而无需对另一个答案中编写的module进行任何修改。@ScottSauyet,感谢您提供的具体input
示例-
// Main.js
import { tree } from './Tree' // <- use modules!
const input =
[ { node: { content: 'abc', wordpress_id: 196, wordpress_parent: 193 } }
, { node: { content: 'def', wordpress_id: 193, wordpress_parent: null } } // <- !
, { node: { content: 'ghi', wordpress_id: 199, wordpress_parent: 193 } }
, { node: { content: 'jkl', wordpress_id: 207, wordpress_parent: null } } // <- !
, { node: { content: 'mno', wordpress_id: 208, wordpress_parent: 207 } }
, { node: { content: 'pqr', wordpress_id: 209, wordpress_parent: 208 } }
, { node: { content: 'stu', wordpress_id: 224, wordpress_parent: 207 } }
]
const result =
tree // <- make a tree
( input // <- array of nodes
, ({ node }) => node.wordpress_parent // <- foreign key
, ({ node }, child) => // <- node reconstructor function
({ node: { ...node, child: child(node.wordpress_id) } }) // <- primary key
)
console.log(JSON.stringify(result, null, 2))
输出 -
[
{
"node": {
"content": "def",
"wordpress_id": 193,
"wordpress_parent": null,
"child": [
{
"node": {
"content": "abc",
"wordpress_id": 196,
"wordpress_parent": 193,
"child": []
}
},
{
"node": {
"content": "ghi",
"wordpress_id": 199,
"wordpress_parent": 193,
"child": []
}
}
]
}
},
{
"node": {
"content": "jkl",
"wordpress_id": 207,
"wordpress_parent": null,
"child": [
{
"node": {
"content": "mno",
"wordpress_id": 208,
"wordpress_parent": 207,
"child": [
{
"node": {
"content": "pqr",
"wordpress_id": 209,
"wordpress_parent": 208,
"child": []
}
}
]
}
},
{
"node": {
"content": "stu",
"wordpress_id": 224,
"wordpress_parent": 207,
"child": []
}
}
]
}
}
]
在 中input
,我曾经wordpress_parent = null
代表一个根节点。0
如果需要,我们可以在您的原始程序中使用like。tree
接受第四个参数 ,root
即要选择作为树基础的节点。默认是null
但我们可以指定0
,比如 -
const input =
[ { node: { content: 'abc', wordpress_id: 196, wordpress_parent: 193 } }
, { node: { content: 'def', wordpress_id: 193, wordpress_parent: 0 } } // <- !
, { node: { content: 'ghi', wordpress_id: 199, wordpress_parent: 193 } }
, { node: { content: 'jkl', wordpress_id: 207, wordpress_parent: 0 } } // <- !
, { node: { content: 'mno', wordpress_id: 208, wordpress_parent: 207 } }
, { node: { content: 'pqr', wordpress_id: 209, wordpress_parent: 208 } }
, { node: { content: 'stu', wordpress_id: 224, wordpress_parent: 207 } }
]
const result =
tree
( input
, ({ node }) => node.wordpress_parent
, ({ node }, child) =>
({ node: { ...node, child: child(node.wordpress_id) } })
, 0 // <- !
)
console.log(JSON.stringify(result, null, 2))
// same output ...
为了使这篇文章完整,我将包含该Tree
module的副本-
// 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 node shape
const one = (single) =>
maker(single, next => many(cache.get(next)))
return many(cache.get(root))
}
export { empty, tree } // <- public interface
和Index
module依赖 -
// 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 value shape
, empty()
)
export { empty, index, append } // <- public interface
为了获得更多见解,我鼓励您阅读原始问答。