将php数组重新排列为嵌套的分层数组

将php数组重新排列为嵌套的分层数组,php,arrays,hierarchy,taxonomy,Php,Arrays,Hierarchy,Taxonomy,如何使用php将数组#1转换为数组#2结构 第一个数组是数据库对一系列生物体的查询结果,每个生物体都按其顺序、科、属、种进行分类。等级上的种是各种属的子分类,属分类是各种科的子分类等 就名称空间而言,您可以这样理解: 索引[0]中的项目-->半翅目盲蝽科卡纳卡米里斯 索引[1]中的项目-->半翅目。盲蝽科。新盲蝽科 数组#1的键之间存在一种父/子关系,如下所示: “Rank_Order”值是“Rank_Family”值的父级 “秩族”值是“秩属”值的父级 “秩_属”值是“秩_种”值的父项 数

如何使用php将数组#1转换为数组#2结构

第一个数组是数据库对一系列生物体的查询结果,每个生物体都按其顺序、科、属、种进行分类。等级上的种是各种属的子分类,属分类是各种科的子分类等

就名称空间而言,您可以这样理解:

索引[0]中的项目-->半翅目盲蝽科卡纳卡米里斯
索引[1]中的项目-->半翅目。盲蝽科。新盲蝽科

数组#1的键之间存在一种父/子关系,如下所示:

  • “Rank_Order”值是“Rank_Family”值的父级
  • “秩族”值是“秩属”值的父级
  • “秩_属”值是“秩_种”值的父项
数组#1:

以下数组是我需要的数组结构: 数组#2:


我在stack overflow中看到了类似的问题,但我没有在我的案例中使用它们。例如,

我不认为这对于真正的大型阵列来说是非常高效的,但它适用于您的场景()


更改的动机是什么?为什么不使用OOP?您说类似的问题在您的案例中不可用,但没有向我们提供有关您的特定阵列结构的任何详细信息。。。你的问题是什么?我想取第一个数组并从中创建第二个数组。我将把两个代码块之间的语句编辑成一个问题,抱歉,这样做的动机是,在我将数组编码为JSON并用于其他目的之前,第二个数组是我所需要的结构。由于键名称不同,不清楚第一个数组如何转换为第二个数组。另外,为什么不直接将其转换为json,为什么您必须经历嵌套数组的另一个阶段?似乎需要将
$result
推到某个地方。我在努力理解where@johowie:啊,我错过了第二个函数中的初始化,但实际上它不是必需的。您只需捕获对Hierth的调用的输出,该调用确实按要求工作,尽管计算时间似乎确实是个问题。@johowie,我不清楚是否可以做得更好。对于深度为M和N的不同根元素,这最多需要O(MN)时间,对于完整的层次结构,这应该会做得更好。在这里,M是常数,所以算法的复杂性,不管你信不信,是线性的应该是
返回$result,对吗?。当我在我的本地主机(MAMP)上运行这个php脚本时,它会花费很长时间,并且对于大于少数节点的数组,它只会因服务器错误而超时。您在ideone.com上的示例@Mark的运行速度要快得多。我不明白为什么我的本地主机不喜欢这个!
Array
(
    [0] => Array
        (
            ['Rank_Order'] => 'Hemiptera'
            ['Rank_Family'] => 'Miridae'
            ['Rank_Genus'] => 'Kanakamiris'
            ['Rank_Species'] => ''
        )   
    [1] => Array
        (
            ['Rank_Order'] => 'Hemiptera'
            ['Rank_Family'] => 'Miridae'
            ['Rank_Genus'] => 'Neophloeobia'
            ['Rank_Species'] => 'incisa'
        )
    [2] => Array
        (
            ['Rank_Order'] => 'Hemiptera'
            ['Rank_Family'] => 'Noridae'
            ['Rank_Genus'] => 'Canelbia'
            ['Rank_Species'] => 'Arissa'
        )
)
Array(
    [name]     => 'Hemiptera'
    [children] => Array(

        [0] => Array(
            [name]     => 'Miridae'
            [children] => Array(

                [0] => Array(
                    [name]     => 'Kanakamiris'
                    [children] => Array(
                    )
                )
                [1] => Array(
                    [name]     => 'Neophloeobia'
                    [children] => Array(

                        [0] => Array(
                            [name] => 'incisa'
                            [children] => Array(
                            )
                        )
                    )
                )
            )
        )
        [1] => Array(
            [name]     => 'Noridae'
            [children] => Array(

                [0] => Array(
                    [name]     => 'Canelbia'
                    [children] => Array(

                        [0] => Array(
                            [name] => 'Arissa'
                            [children] => Array(
                            )
                        )
                    )
                )
            )
        )
    )
)
 $array = ...
 $levels = array('Rank_Order', 'Rank_Family', 'Rank_Genus', 'Rank_Species');

 function get_children($parent, $lev, $orig, $levels){
     if($lev + 1 > count($levels)){
          return array();
     }

     $seen = array();
     $children = array();
     foreach($orig as $node){
         if($node[$levels[$lev]] == $parent && !in_array($node[$levels[$lev+1]], $seen)){
             $seen[] = $node[$levels[$lev+1]];
             $children[] = get_children($node[$levels[$lev+1]], $lev+1, $orig, $levels);
         }
     }
     return array('name' => $parent, 'children' => $children);
 }

 function hier($orig, $levels){
     $seen = array();
     $result = array();
     foreach($orig as $node){
         if(!in_array($node[$levels[0]], $seen)){
              $seen[] = $node[$levels[0]];
              $result[] = get_children($node[$levels[0]], 0, $orig, $levels);
         }
     }
     return $result;
 }

 print_r($array);
 print_r(hier($array, $levels));