PHP 构建多层树的逻辑
PHP logic to build multi level tree
已更新
我有以下数组,例如:
[{id:1},{id:2}{id:3},{id:4},{id:5},...{id:20}]
请问如何生成如下图的JSONobject,才能在图1中实现下面的树?它不需要 parent id,因为它是先到先得,每个节点只会有直接的 3 个孩子。
我认为它将 运行 通过函数并将 children
附加到 object。我也希望将来控制孩子的数量。提前致谢
JSON object
{
"tree": {
"id": 1,
"children": [
{
"id": 2,
"children": [
{
"id": 5,
"children": [
{
"id": 11
},
{
"id": 12
},
{
"id": 13
}
]
},
{
"id": 6
},
{
"id": 7
}
]
},
{
"id": 3,
"children": [
{
"id": 8
},
{
"id": 9
},
{
"id": 10
}
]
},
{
"id": 4,
"children": [
{
"id": 11
},
{
"id": 12
},
{
"id": 13
}
]
}
]
}
}
图 1:树图
首先,您的 JSON 对象包含重复的 ID。
所以逻辑是 - 取第一个元素,将其标记为 current_parent。每个后续元素都放入 parents_queue 并放入 current_parent 子数组。如果 current_parent 子数组长度为 3 个元素,则从 parents_queue 中取出下一个节点并将其标记为 current_parent。
示例代码:
// Generate test data
$data = [];
foreach(range(1,20) as $i)
$data[] = ['id' => $i];
// Tree root and helper vars
$root = null;
$current_parent_node_pointer = null;
$parents_queue = [];
for( $i = 0; $i < count($data); $i++ ){
$node = &$data[$i];
// Not the first element
if( $i ){
if( empty( $current_parent_node_pointer['children'] ) )
$current_parent_node_pointer['children'] = [];
// Add the node to current parent
$current_parent_node_pointer['children'][] = &$node;
// Current parent has 3 children now, take a new one from the queue;
if( count( $current_parent_node_pointer['children'] ) == 3 ){
unset($current_parent_node_pointer); // destroy the reference before assining a new value
$current_parent_node_pointer = &$parents_queue[0];
array_shift($parents_queue); // remove current parent from the queue
}
// Add current node to the parents queue
$parents_queue[] = &$node;
}
// First element; actually an initialization
else {
$root = &$node;
$current_parent_node_pointer = &$node;
}
}
$json = json_encode( ['tree' => $root] );
UPD:如果你的输入是一个对象数组,代码会稍微简单一些(不需要引用用法):
// Generate test data
$data = [];
foreach(range(1,20) as $i)
$data[] = (object)['id' => $i];
// Tree root and helper vars
$root = null;
$current_parent_node_pointer = null;
$parents_queue = [];
foreach($data as $node){
// Not the first element
if( !empty($current_parent_node_pointer) ){
if( empty( $current_parent_node_pointer->children ) )
$current_parent_node_pointer->children = [];
// Add the node to current parent
$current_parent_node_pointer->children[] = $node;
// Current parent has 3 children now, take a new one from the queue;
if( count( $current_parent_node_pointer->children ) == 3 )
$current_parent_node_pointer = array_shift($parents_queue);
// Add current node to the parents queue
$parents_queue[] = $node;
}
// First element; actually an initialization
else {
$root = $node;
$current_parent_node_pointer = $node;
}
}
$json = json_encode( ['tree' => $root] );
已更新
我有以下数组,例如:
[{id:1},{id:2}{id:3},{id:4},{id:5},...{id:20}]
请问如何生成如下图的JSONobject,才能在图1中实现下面的树?它不需要 parent id,因为它是先到先得,每个节点只会有直接的 3 个孩子。
我认为它将 运行 通过函数并将 children
附加到 object。我也希望将来控制孩子的数量。提前致谢
JSON object
{
"tree": {
"id": 1,
"children": [
{
"id": 2,
"children": [
{
"id": 5,
"children": [
{
"id": 11
},
{
"id": 12
},
{
"id": 13
}
]
},
{
"id": 6
},
{
"id": 7
}
]
},
{
"id": 3,
"children": [
{
"id": 8
},
{
"id": 9
},
{
"id": 10
}
]
},
{
"id": 4,
"children": [
{
"id": 11
},
{
"id": 12
},
{
"id": 13
}
]
}
]
}
}
图 1:树图
首先,您的 JSON 对象包含重复的 ID。
所以逻辑是 - 取第一个元素,将其标记为 current_parent。每个后续元素都放入 parents_queue 并放入 current_parent 子数组。如果 current_parent 子数组长度为 3 个元素,则从 parents_queue 中取出下一个节点并将其标记为 current_parent。 示例代码:
// Generate test data
$data = [];
foreach(range(1,20) as $i)
$data[] = ['id' => $i];
// Tree root and helper vars
$root = null;
$current_parent_node_pointer = null;
$parents_queue = [];
for( $i = 0; $i < count($data); $i++ ){
$node = &$data[$i];
// Not the first element
if( $i ){
if( empty( $current_parent_node_pointer['children'] ) )
$current_parent_node_pointer['children'] = [];
// Add the node to current parent
$current_parent_node_pointer['children'][] = &$node;
// Current parent has 3 children now, take a new one from the queue;
if( count( $current_parent_node_pointer['children'] ) == 3 ){
unset($current_parent_node_pointer); // destroy the reference before assining a new value
$current_parent_node_pointer = &$parents_queue[0];
array_shift($parents_queue); // remove current parent from the queue
}
// Add current node to the parents queue
$parents_queue[] = &$node;
}
// First element; actually an initialization
else {
$root = &$node;
$current_parent_node_pointer = &$node;
}
}
$json = json_encode( ['tree' => $root] );
UPD:如果你的输入是一个对象数组,代码会稍微简单一些(不需要引用用法):
// Generate test data
$data = [];
foreach(range(1,20) as $i)
$data[] = (object)['id' => $i];
// Tree root and helper vars
$root = null;
$current_parent_node_pointer = null;
$parents_queue = [];
foreach($data as $node){
// Not the first element
if( !empty($current_parent_node_pointer) ){
if( empty( $current_parent_node_pointer->children ) )
$current_parent_node_pointer->children = [];
// Add the node to current parent
$current_parent_node_pointer->children[] = $node;
// Current parent has 3 children now, take a new one from the queue;
if( count( $current_parent_node_pointer->children ) == 3 )
$current_parent_node_pointer = array_shift($parents_queue);
// Add current node to the parents queue
$parents_queue[] = $node;
}
// First element; actually an initialization
else {
$root = $node;
$current_parent_node_pointer = $node;
}
}
$json = json_encode( ['tree' => $root] );