我有一个大问题(显然很容易解决),我已经尝试了24个多小时来创建一个函数,以深度将数组转换为多维。
我的数组是
$array = array(
array("name" => "Root_1", "depth"=> "1"),
array("name" => "Children","depth"=> "2"),
array("name" => "Children", "depth"=> "2"),
array("name" => "Children", "depth"=> "2"),
array("name" => "Children","depth"=> "3"),
array("name" => "Children","depth"=> "3"),
array("name" => "Children","depth"=> "3"),
array("name" => "Root_2", "depth"=> "1"),
array("name" => "Children", "depth"=> "2"),
array("name" => "Children", "depth"=> "2"),
array("name" => "Children", "depth"=> "2")
)
我希望输出为:
$array = array(
array("name" => "Root_1", "depth"=> "1", "children" => array(
array("name" => "Children", "depth"=> "2", "children" => array()),
array("name" => "Children", "depth"=> "2", "children" => array()),
array("name" => "Children", "depth"=> "2", "children" => array(
array("name" => "Children", "depth"=> "3", "children" => array()),
array("name" => "Children", "depth"=> "3", "children" => array()),
array("name" => "Children", "depth"=> "3", "children" => array())
)
)),
array("name" => "Root_2", "depth"=> "1", "children" => array(
array("name" => "Children", "depth"=> "2", "children" => array()),
array("name" => "Children", "depth"=> "2", "children" => array()),
array("name" => "Children", "depth"=> "2", "children" => array(
array("name" => "Children", "depth"=> "3", "children" => array()),
array("name" => "Children", "depth"=> "3", "children" => array()),
array("name" => "Children", "depth"=> "3", "children" => array())
)
)),
);
我尝试过的事情:
<?php
function createArray($array, $depth) {
$result = array();
$item = array();
if(isset($array["depth"])) {
if(intval($array["depth"]) >= $depth) {
array_push($result, $array);
}
} else {
foreach($array as $value) {
$depthToInt = intval($value["depth"]);
if($depthToInt === $depth) {
array_push($result, $value);
$item = $value;
} else {
$item["children"] = createArray($value, $item["depth"]);
}
}
}
return $result;
}
答案 0 :(得分:3)
我来晚了,但是如果您对非递归解决方案感兴趣,这是一个简单的仅一次通过循环( O(n)):
<?php
function treeify(array $input): array
{
$result = [];
$path = [];
foreach ($input as &$entry) {
$entry['children'] = [];
$depth = $entry['depth'] - 1;
$path = \array_slice($path, 0, $depth);
$path[] = &$entry;
0 === $depth
? $result[] = &$entry
: $path[$depth - 1]['children'][] = &$entry;
}
return $result;
}
print_r(treeify([
['name' => 'Root_1', 'depth' => 1],
['name' => 'Children', 'depth' => 2],
['name' => 'Children', 'depth' => 2],
['name' => 'Children', 'depth' => 2],
['name' => 'Children', 'depth' => 3],
['name' => 'Children', 'depth' => 3],
['name' => 'Children', 'depth' => 3],
['name' => 'Children', 'depth' => 4],
['name' => 'Children', 'depth' => 2],
['name' => 'Root_2', 'depth'=> 1],
['name' => 'Children', 'depth' => 2],
['name' => 'Children', 'depth' => 2],
['name' => 'Children', 'depth' => 2],
['name' => 'Children', 'depth' => 3],
['name' => 'Root_3', 'depth' => 1],
['name' => 'Root_4', 'depth' => 1],
['name' => 'Children', 'depth' => 2],
]));
答案 1 :(得分:2)
好的,很明显,我们需要一个递归解决方案。
对于每个项目(从虚拟根目录开始),我们要检索子级。假设我们通过过滤掉所有不是 孩子的孩子来获得孩子。
我们的过滤条件是什么?
所以我们需要:
这就是我最后得到的。我认为这不是完美的选择(我隐约地怀疑我的极限逻辑),但是对于您的示例数据来说,大部分都在那儿。
$array = array(
array( 'name' => 'Root_1', 'depth' => '1' ),
array( 'name' => 'Children 1-1', 'depth' => '2' ),
array( 'name' => 'Children 1-2', 'depth' => '2' ),
array( 'name' => 'Children 1-2-1', 'depth' => '3' ),
array( 'name' => 'Children 1-3', 'depth' => '2' ),
array( 'name' => 'Children 1-3-1', 'depth' => '3' ),
array( 'name' => 'Children 1-3-2', 'depth' => '3' ),
array( 'name' => 'Children 1-3-3', 'depth' => '3' ),
array( 'name' => 'Root_2', 'depth' => '1' ),
array( 'name' => 'Children 2-1', 'depth' => '2' ),
array( 'name' => 'Children 2-2', 'depth' => '2' ),
array( 'name' => 'Children 2-3', 'depth' => '2' ),
array( 'name' => 'Children 2-3-1', 'depth' => '3' ),
array( 'name' => 'Children 2-3-2', 'depth' => '3' ),
array( 'name' => 'Children 2-3-3', 'depth' => '3' ),
);
function getChildren( $array, $index = - 1 ) {
$depth = isset( $array[ $index ]['depth'] ) ? (int) $array[ $index ]['depth'] : 0;
$limit = $index === - 1 ? count( $array ) - 1 : findLimit( $array, $index );
$result = array_filter( $array, function ( $item, $key ) use ( $index, $depth, $limit ) {
$isDeeper = (int) $item['depth'] === $depth + 1;
$isAfter = $key > $index;
$isBeforeLimit = $key <= $limit;
return $isDeeper && $isAfter && $isBeforeLimit;
}, ARRAY_FILTER_USE_BOTH );
foreach ( $result as $key => $item ) {
$result[ $key ]['children'] = getChildren( $array, $key );
}
return $result;
}
function findLimit( $array, $index ) {
$depth = (int) $array[ $index ]['depth'];
$limit = $index;
$current = $limit + 1;
while ( isset( $array[ $current ] ) && ( (int) $array[ $current ]['depth'] > $depth ) ) {
$current ++;
$limit ++;
}
return $limit;
}
$result = getChildren( $array );
var_dump( $result );
结果:
array(2) {
[0]=>
array(3) {
["name"]=>
string(6) "Root_1"
["depth"]=>
string(1) "1"
["children"]=>
array(3) {
[1]=>
array(3) {
["name"]=>
string(12) "Children 1-1"
["depth"]=>
string(1) "2"
["children"]=>
array(0) {
}
}
[2]=>
array(3) {
["name"]=>
string(12) "Children 1-2"
["depth"]=>
string(1) "2"
["children"]=>
array(1) {
[3]=>
array(3) {
["name"]=>
string(14) "Children 1-2-1"
["depth"]=>
string(1) "3"
["children"]=>
array(0) {
}
}
}
}
[4]=>
array(3) {
["name"]=>
string(12) "Children 1-3"
["depth"]=>
string(1) "2"
["children"]=>
array(3) {
[5]=>
array(3) {
["name"]=>
string(14) "Children 1-3-1"
["depth"]=>
string(1) "3"
["children"]=>
array(0) {
}
}
[6]=>
array(3) {
["name"]=>
string(14) "Children 1-3-2"
["depth"]=>
string(1) "3"
["children"]=>
array(0) {
}
}
[7]=>
array(3) {
["name"]=>
string(14) "Children 1-3-3"
["depth"]=>
string(1) "3"
["children"]=>
array(0) {
}
}
}
}
}
}
[8]=>
array(3) {
["name"]=>
string(6) "Root_2"
["depth"]=>
string(1) "1"
["children"]=>
array(3) {
[9]=>
array(3) {
["name"]=>
string(12) "Children 2-1"
["depth"]=>
string(1) "2"
["children"]=>
array(0) {
}
}
[10]=>
array(3) {
["name"]=>
string(12) "Children 2-2"
["depth"]=>
string(1) "2"
["children"]=>
array(0) {
}
}
[11]=>
array(3) {
["name"]=>
string(12) "Children 2-3"
["depth"]=>
string(1) "2"
["children"]=>
array(3) {
[12]=>
array(3) {
["name"]=>
string(14) "Children 2-3-1"
["depth"]=>
string(1) "3"
["children"]=>
array(0) {
}
}
[13]=>
array(3) {
["name"]=>
string(14) "Children 2-3-2"
["depth"]=>
string(1) "3"
["children"]=>
array(0) {
}
}
[14]=>
array(3) {
["name"]=>
string(14) "Children 2-3-3"
["depth"]=>
string(1) "3"
["children"]=>
array(0) {
}
}
}
}
}
}
}