[英]Regroup array to tree structure in PHP
I have an array like this one: 我有一个像这样的数组:
$array = array(
array('id' => 'foo.bar'),
array('id' => 'foo'),
array('id' => 'foo.baz.bar'),
array('id' => 'foo.bar.bar'),
);
I can split
the id
fields to get them as paths, and then I'd like to sort them into a tree... I tried this: 我可以
split
id
字段split
为路径,然后将它们排序为树...
$result = array();
foreach($array as $element) {
$path = explode('.', $element['id']);
$subtree = $result;
while(!empty($path)) {
$path_element = array_shift($path);
if(empty($path_element)) {
$subtree['data'] = $element;
} else {
if(!is_array($subtree[$path_element])) {
$subtree[$path_element] = array();
}
$subtree = $subtree[$path_element];
}
}
}
But all I get is a load of warnings and an empty $res
-Array. 但是我得到的只是大量警告和一个空的
$res
-Array。
PHP Notice: Undefined index: foo in tree.php on line 24
PHP Stack trace:
PHP 1. {main}() tree.php:0
PHP Notice: Undefined index: bar in tree.php on line 24
PHP Stack trace:
PHP 1. {main}() tree.php:0
PHP Notice: Undefined index: foo in tree.php on line 24
PHP Stack trace:
PHP 1. {main}() tree.php:0
PHP Notice: Undefined index: foo in tree.php on line 24
PHP Stack trace:
PHP 1. {main}() tree.php:0
PHP Notice: Undefined index: baz in tree.php on line 24
PHP Stack trace:
PHP 1. {main}() tree.php:0
PHP Notice: Undefined index: bar in tree.php on line 24
PHP Stack trace:
PHP 1. {main}() tree.php:0
PHP Notice: Undefined index: foo in tree.php on line 24
PHP Stack trace:
PHP 1. {main}() tree.php:0
PHP Notice: Undefined index: bar in tree.php on line 24
PHP Stack trace:
PHP 1. {main}() tree.php:0
PHP Notice: Undefined index: bar in tree.php on line 24
PHP Stack trace:
PHP 1. {main}() tree.php:0
(Line 24 is $s = $s[$pe];
) (第24行是
$s = $s[$pe];
)
Any hint? 有什么提示吗?
EDIT : My desired output would be like this 编辑 :我想要的输出将是这样
$res = array(
'foo' => array(
'data' => ...
'bar' => array(
'data' => ...
'bar' => array(
'data' => ...
),
),
'baz' => array(
'bar' => array(
'data' => ...
),
),
),
);
The data
elements are the original elements from the array. data
元素是数组中的原始元素。
The code below generates the following result: 下面的代码生成以下结果:
Array
(
[foo] => Array
(
[data] => ...
[baz] => Array
(
[bar] => Array
(
[data] => ...
)
)
[bar] => Array
(
[bar] => Array
(
[data] => ...
)
)
)
)
I renamed some of you're variables... 我重命名了一些变量...
$array = array(
array('id' => 'foo.bar'),
array('id' => 'foo'),
array('id' => 'foo.baz.bar'),
array('id' => 'foo.bar.bar'),
);
$res = array();
foreach($array as $e) {
$parts = explode('.', $e['id']);
$temp = &$res;
foreach($parts as $key => $el) {
if (!isset($temp[$el])) $temp[$el] = array();
if ($key == count($parts)-1) $temp[$el] = array('data' => '...');
$temp = &$temp[$el];
}
}
print_r($res);
Make $s referencing $res, using the &
. 使用
&
使$ s引用$ res。 This will pass the data by reference instead of by value. 这将通过引用而不是通过值传递数据。
$a = array(
array('id' => 'foo.bar'),
array('id' => 'foo'),
array('id' => 'foo.baz.bar'),
array('id' => 'foo.bar.bar'),
);
$res = array();
foreach($a as $e) {
$p = explode('.', $e['id']);
$s = &$res;
while(!empty($p)) {
$pe = array_shift($p);
if(empty($p)) {
$s['data'] = $e;
} else {
if(!isset($s[$pe])) {
$s[$pe] = array();
}
$s = &$s[$pe];
}
}
}
echo '<pre>';
print_r($res);
echo '</pre>';
results in 结果是
Array
(
[foo] => Array
(
[data] => Array
(
[id] => foo.bar
)
[baz] => Array
(
[data] => Array
(
[id] => foo.baz.bar
)
)
[bar] => Array
(
[data] => Array
(
[id] => foo.bar.bar
)
)
)
[data] => Array
(
[id] => foo
)
)
Recursion is your answer. 递归是您的答案。
and you would need something along the lines of: 并且您需要以下方面的东西:
<?php
$a = array(
array('id' => 'foo.bar'),
array('id' => 'foo'),
array('id' => 'foo.baz.bar'),
array('id' => 'foo.bar.bar'),
);
function createTree($path) {
if ( count($path) === 1 ) {
return array($path[0]=>array('data'=>'some random data here'));
} else {
$currentRoot = array_shift($path);
return array($currentRoot => createTree($path));
}
}
$result = array();
foreach ( $a as $item ) {
$result = array_merge_recursive(
$result,
createTree(
explode('.',$item['id'])
)
);
}
// $result now is what you wanted
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.