从 PHP 中的二维数组创建非二叉树
Creating a non-binary tree from a two-dimensional array in PHP
我正在尝试根据存储在二维数组中的值设置由 KendoUI 提供的 Treeview。不幸的是,我无法全神贯注于数据源的创建,它应该是 JavaScript.
中使用的多维数组
方案是递归读取二维数组,将PHP中的数据源逐条构造为字符串,然后传递给JavaScript函数
二维数组示例:
(1维中的key是父元素的'name';
子元素的键是一个整数,值为子元素的 'name')
Array
(
[1] => Array
(
[0] => 2
[1] => 3
[2] => 4
)
[2] => Array
(
[0] => 3
)
[3] => Array
(
[0] => 3
[1] => 1
)
[4] => Array
(
[0] => 2
)
)
它应该是什么样子的一个例子(有两个值):
dataSource: [
{ text: "1", items: [
{ text: "2", items: [
{ text: "3" }
]},
{ text: "3" , items: [
{ text: "3" },
{ text: "1" }
]},
{ text: "4", items: [
{ text: "2", items: [
{ text: "3", items: [
{ text: "3" },
{ text: "1" }
] }
] }
] }
] },
{ text: "2", items: [
{ text: "3", items: [
{ text: "3" },
{ text: "1" , items: [
{ text: "1" },
{ text: "3" },
{ text: "4", items: [
{ text: "2" }
] }
] }
] }
] }
]
我知道我必须考虑算法中的无限循环。从树的 'leaf' 到 'root' a 的直接路径最多只能包含单个值的 2 个实例。
如果满足该条件,则分支将被放弃,不应再进一步填充。
任何人都可以给我一些正确方向的指示吗?
有什么 PHP class 可以用来简化这个问题吗?
如果您想将 PHP 结构转换为简单的 JS 映射,那么您可以在 JS 中使用类似这样的东西来创建您的结构:
const makeTree = (data, nodes = [...data .keys ()], path = []) => {
const res = nodes
.filter ((id) => path .filter (x => x == id) .length < 2)
.map((id) => {
const kids = makeTree(data, data .get (id), path .concat (id));
return {
text: id,
...(kids .length ? {items: kids} : {})
}
})
return res
}
const data = new Map([
['1', ['2', '3', '4']],
['2', ['3']],
['3', ['3', '1']],
['4', ['2']]
])
console .log (
makeTree (data)
)
makeTree
接受一个像上面那样的 Map,一个包含分支值列表的数组,以及一个包含当前路径的数组。初始调用将分支值默认为 Map 的键,并将路径默认为空数组。后续调用通过在地图中查找当前值并将该值附加到路径来计算节点。
我发现在生成的对象中也包含 path
有助于调试:
return {
text: id,
path: path.join('') + id,
...(kids .length ? {items: kids} : {})
}
配合合适的display
函数,可以分层查看输出:
/*
1 (1)
...2 (12)
.......3 (123)
...........3 (1233)
...............1 (12331)
...................2 (123312)
...................4 (123314)
.......................2 (1233142)
...........1 (1231)
...............2 (12312)
...................3 (123123)
...............3 (12313)
...............4 (12314)
...................2 (123142)
.......................3 (1231423)
...3 (13)
.......3 (133)
...........1 (1331)
...............2 (13312)
...............4 (13314)
...................2 (133142)
.......1 (131)
...........2 (1312)
...............3 (13123)
...........3 (1313)
...........4 (1314)
...............2 (13142)
...................3 (131423)
...4 (14)
.......2 (142)
...........3 (1423)
...............3 (14233)
...................1 (142331)
.......................2 (1423312)
.......................4 (1423314)
...........................2 (14233142)
...............1 (14231)
...................2 (142312)
.......................3 (1423123)
...................3 (142313)
...................4 (142314)
.......................2 (1423142)
...........................3 (14231423)
2 (2)
...3 (23)
.......3 (233)
...........1 (2331)
...............2 (23312)
...............4 (23314)
...................2 (233142)
.......1 (231)
...........2 (2312)
...............3 (23123)
...................1 (231231)
.......................4 (2312314)
...........3 (2313)
...............1 (23131)
...................2 (231312)
...................4 (231314)
.......................2 (2313142)
...........4 (2314)
...............2 (23142)
...................3 (231423)
.......................1 (2314231)
...........................4 (23142314)
3 (3)
...3 (33)
.......1 (331)
...........2 (3312)
...........4 (3314)
...............2 (33142)
...1 (31)
.......2 (312)
...........3 (3123)
...............1 (31231)
...................2 (312312)
...................4 (312314)
.......................2 (3123142)
.......3 (313)
...........1 (3131)
...............2 (31312)
...............4 (31314)
...................2 (313142)
.......4 (314)
...........2 (3142)
...............3 (31423)
...................1 (314231)
.......................2 (3142312)
.......................4 (3142314)
...........................2 (31423142)
4 (4)
...2 (42)
.......3 (423)
...........3 (4233)
...............1 (42331)
...................2 (423312)
...................4 (423314)
.......................2 (4233142)
...........1 (4231)
...............2 (42312)
...................3 (423123)
.......................1 (4231231)
...........................4 (42312314)
...............3 (42313)
...................1 (423131)
.......................2 (4231312)
.......................4 (4231314)
...........................2 (42313142)
...............4 (42314)
...................2 (423142)
.......................3 (4231423)
...........................1 (42314231)
*/
如果您确实希望输入值是数字,text
节点是字符串,您可以在生成的对象中将 id
包装为 String(id)
。
此代码依赖于每个映射值中的每个条目作为映射中的键。我不知道如果不这样做会发生什么。据我所知,它会除以零,发射核导弹,并偷走你的男朋友,所以要小心!
我正在尝试根据存储在二维数组中的值设置由 KendoUI 提供的 Treeview。不幸的是,我无法全神贯注于数据源的创建,它应该是 JavaScript.
中使用的多维数组方案是递归读取二维数组,将PHP中的数据源逐条构造为字符串,然后传递给JavaScript函数
二维数组示例: (1维中的key是父元素的'name'; 子元素的键是一个整数,值为子元素的 'name')
Array
(
[1] => Array
(
[0] => 2
[1] => 3
[2] => 4
)
[2] => Array
(
[0] => 3
)
[3] => Array
(
[0] => 3
[1] => 1
)
[4] => Array
(
[0] => 2
)
)
它应该是什么样子的一个例子(有两个值):
dataSource: [
{ text: "1", items: [
{ text: "2", items: [
{ text: "3" }
]},
{ text: "3" , items: [
{ text: "3" },
{ text: "1" }
]},
{ text: "4", items: [
{ text: "2", items: [
{ text: "3", items: [
{ text: "3" },
{ text: "1" }
] }
] }
] }
] },
{ text: "2", items: [
{ text: "3", items: [
{ text: "3" },
{ text: "1" , items: [
{ text: "1" },
{ text: "3" },
{ text: "4", items: [
{ text: "2" }
] }
] }
] }
] }
]
我知道我必须考虑算法中的无限循环。从树的 'leaf' 到 'root' a 的直接路径最多只能包含单个值的 2 个实例。 如果满足该条件,则分支将被放弃,不应再进一步填充。
任何人都可以给我一些正确方向的指示吗? 有什么 PHP class 可以用来简化这个问题吗?
如果您想将 PHP 结构转换为简单的 JS 映射,那么您可以在 JS 中使用类似这样的东西来创建您的结构:
const makeTree = (data, nodes = [...data .keys ()], path = []) => {
const res = nodes
.filter ((id) => path .filter (x => x == id) .length < 2)
.map((id) => {
const kids = makeTree(data, data .get (id), path .concat (id));
return {
text: id,
...(kids .length ? {items: kids} : {})
}
})
return res
}
const data = new Map([
['1', ['2', '3', '4']],
['2', ['3']],
['3', ['3', '1']],
['4', ['2']]
])
console .log (
makeTree (data)
)
makeTree
接受一个像上面那样的 Map,一个包含分支值列表的数组,以及一个包含当前路径的数组。初始调用将分支值默认为 Map 的键,并将路径默认为空数组。后续调用通过在地图中查找当前值并将该值附加到路径来计算节点。
我发现在生成的对象中也包含 path
有助于调试:
return {
text: id,
path: path.join('') + id,
...(kids .length ? {items: kids} : {})
}
配合合适的display
函数,可以分层查看输出:
/*
1 (1)
...2 (12)
.......3 (123)
...........3 (1233)
...............1 (12331)
...................2 (123312)
...................4 (123314)
.......................2 (1233142)
...........1 (1231)
...............2 (12312)
...................3 (123123)
...............3 (12313)
...............4 (12314)
...................2 (123142)
.......................3 (1231423)
...3 (13)
.......3 (133)
...........1 (1331)
...............2 (13312)
...............4 (13314)
...................2 (133142)
.......1 (131)
...........2 (1312)
...............3 (13123)
...........3 (1313)
...........4 (1314)
...............2 (13142)
...................3 (131423)
...4 (14)
.......2 (142)
...........3 (1423)
...............3 (14233)
...................1 (142331)
.......................2 (1423312)
.......................4 (1423314)
...........................2 (14233142)
...............1 (14231)
...................2 (142312)
.......................3 (1423123)
...................3 (142313)
...................4 (142314)
.......................2 (1423142)
...........................3 (14231423)
2 (2)
...3 (23)
.......3 (233)
...........1 (2331)
...............2 (23312)
...............4 (23314)
...................2 (233142)
.......1 (231)
...........2 (2312)
...............3 (23123)
...................1 (231231)
.......................4 (2312314)
...........3 (2313)
...............1 (23131)
...................2 (231312)
...................4 (231314)
.......................2 (2313142)
...........4 (2314)
...............2 (23142)
...................3 (231423)
.......................1 (2314231)
...........................4 (23142314)
3 (3)
...3 (33)
.......1 (331)
...........2 (3312)
...........4 (3314)
...............2 (33142)
...1 (31)
.......2 (312)
...........3 (3123)
...............1 (31231)
...................2 (312312)
...................4 (312314)
.......................2 (3123142)
.......3 (313)
...........1 (3131)
...............2 (31312)
...............4 (31314)
...................2 (313142)
.......4 (314)
...........2 (3142)
...............3 (31423)
...................1 (314231)
.......................2 (3142312)
.......................4 (3142314)
...........................2 (31423142)
4 (4)
...2 (42)
.......3 (423)
...........3 (4233)
...............1 (42331)
...................2 (423312)
...................4 (423314)
.......................2 (4233142)
...........1 (4231)
...............2 (42312)
...................3 (423123)
.......................1 (4231231)
...........................4 (42312314)
...............3 (42313)
...................1 (423131)
.......................2 (4231312)
.......................4 (4231314)
...........................2 (42313142)
...............4 (42314)
...................2 (423142)
.......................3 (4231423)
...........................1 (42314231)
*/
如果您确实希望输入值是数字,text
节点是字符串,您可以在生成的对象中将 id
包装为 String(id)
。
此代码依赖于每个映射值中的每个条目作为映射中的键。我不知道如果不这样做会发生什么。据我所知,它会除以零,发射核导弹,并偷走你的男朋友,所以要小心!