我有以下示例数组列表;
$relationships = ['contact', 'property', 'contact.type1', 'contact.type2', 'contact.type1.color1', 'contact.type1.color2'];
我想要一个像这样的结构;
[
contact => [
type1 => [
color1 => [],
color2 => []
],
type2 => []
],
property => []
]
我创建了以下代码;
start();
function start()
{
$myTree = array();
$relations = ['contact', 'property', 'contact.type1', 'contact.type2', 'contact.type1.color1', 'contact.type1.color2'];
foreach ($relations as $relation) {
$myTree = getRelationTree($relation, $myTree);
}
var_dump($myTree);
}
function getRelationTree($name, $tree)
{
$sections = explode('.', $name);
$main = array_shift($sections);
if (!array_search($main, $tree)) {
$tree[$main] = [] ;
}
// Has nested relationships
if (count($sections) > 0) {
$children = [];
$children[] = getRelationTree(join('.',$sections), $children);
$tree[$main] = $children;
}
return $tree;
}
但是,根据上述预期结果,我得到的结果缺少color1
。
你能告诉我我的代码有什么问题吗?我如何修复它以给我想要的结果?感谢
答案 0 :(得分:2)
我刚刚使用引用而不是recurency编写了更简单的代码。
查看我的代码,它包含评论说明发生了什么:
<?php
$relationships = ['contact', 'property', 'contact.type1', 'contact.type2', 'contact.type1.color1', 'contact.type1.color2'];
$tree = [];
foreach($relationships as $path) {
$parts = explode('.', $path);
//represents current position in current $path
$currentNode = &$tree;
foreach($parts as $part) {
//if this part doesn't exist yet, let's create it
if(empty($currentNode[$part])) {
$currentNode[$part] = [];
}
//move forward in out $path position
$currentNode = &$currentNode[$part];
}
//after we finish a particular path, we reset the position.
unset($currentNode);
}
编辑:这是对你错误的解释:
在我分析了您的代码后,我可以在您的函数getRelationTree()
中看到您的错误:
// Has nested relationships
if (count($sections) > 0) {
$children = [];
$children[] = getRelationTree(implode('.',$sections), $children);
$tree[$main] = $children; // <==this line exactly
}
您正在覆盖现有的值。
因此,当您的树已经解析了'contact.type1.color1'
路径并且您正在解析'contact.type1.color2'
时,您将覆盖$tree['contact']
已经具有'type1.color1'
值且新子树的type1.color2
#!/usr/bin/perl
use Modern::Perl;
use Mojolicious::Lite;
use extmod;
sub hello
{
say "hello";
}
get "/" => sub
{
my $c = shift;
extmod::put();
$c->render(text=>"ok");
};
app->start;
。等等。
答案 1 :(得分:0)
这是另一个答案的替代方案,使用递归(准备好复制粘贴):
$relationships = ['contact', 'property', 'contact.type1', 'contact.type2', 'contact.type1.color1', 'contact.type1.color2'];
$arr = array();
foreach($relationships as $value){
add($arr, $value);
}
function add(&$arr, $value){
if(strpos($value, '.') !== false){ // if there are sublevels
$tmp = explode('.', $value, 2); // separate first from rest of levels
$item = $tmp[0]; // get what's before first dot
$children = $tmp[1]; // get what's after the first dot
if(empty($arr[$item])){ // if not yet created, create item
$arr[$item] = array();
}
add($arr[$item], $children); // add the item's child / children
return; // prevent from overriding
}
$arr[$value] = array();
}
echo '<pre>';
print_r($arr);