【问题标题】:Recursively loop through multidimensional to create flat array递归循环遍历多维以创建平面数组
【发布时间】:2012-11-06 17:52:25
【问题描述】:

我有一个如下所示的多维数组:

$trees = array(
    array(
        'name' => 'Parent',
        '__children' => array(
            array(
                'name' => 'Child'
            ),
            array(
                'name' => 'Second Child'
            )
        )
    )
);

数组的深度未知,我需要递归地展平它。所以看起来更像这样:

array(
  array(
    'name' => 'Parent' 
  ),
  array(
    'name' => 'Child' 
  ),
  array(
    'name' => 'Second Child' 
  )
)

我认为这样的事情可能会奏效:

public function flattenTree($trees, $tree = array())
{
    foreach($trees as $item){
        //$i = 1, 2, then 3
        $i = count($tree);
        $tree[$i] = array('name' => $item['name']);
        if(isset($item['__children']))
            $this->flattenTree($item['__children'], $tree);
    }
    return $tree;
}

但这只是给我:(

Array
(
    [0] => Array
        (
            [name] => Parent
        )

)

我不确定如何执行此操作。有可能吗?

作为奖励,我真的需要输出数组看起来像这样(注意名称值已更改):)

array(
  array(
    'name' => 'Parent' 
  ),
  array(
    'name' => 'Parent Child' 
  ),
  array(
    'name' => 'Parent Second Child' 
  )
)

非常感谢您对此提供的帮助。期待解决方案。我被难住了!

【问题讨论】:

  • 不能指定没有索引的数组元素。我确定你现在得到了正确的输出
  • 您的问题是缺少数组中的子元素吗?
  • @mohamed 是的。由于某种原因,输出不包含孩子
  • @JohnConde 您是否有机会从该链接中获取示例并将其应用到此处?我不确定它究竟是如何工作的,尤其是在基于树构建全名时。

标签: php arrays recursion multidimensional-array logic


【解决方案1】:

我有类似的逻辑问题,我使用@Mike 的答案进行了一些重构。

public function flattenRecursive(array &$flat, array $nested, $parentPrepend = false)
{
    foreach( $nested as $item ){
        $prepend = $parentPrepend ? $parentPrepend . '/' . $item['name'] : $item['name'];
        $flat[] = array(
            'name' => $prepend
        );
        if(isset($item['__children']))
            $this->flattenRecursive($flat, $item['__children'], $prepend);
    }
}

【讨论】:

    【解决方案2】:

    代码

    <?php
    
    
    $output_array = array();
    
    $input_array  = array(
        array(
            'name'=>'Parent',
            '__children' => array(
                array(
                    'name' => 'Child'
                ),
                array(
                    'name' => 'Second Child'
                )
            )
        )
    );
    
    echo"<pre>";
    print_r($input_array);
    echo"</pre>";
    
    
    function flatten($arr){
        global $output_array;
        if(is_array($arr)){
            foreach($arr as $key=>$value){
                if($key=="name" && !is_array($value)){
                    $output_array[] = array($key=>$value);
                }
                elseif(is_array($value)){
                    flatten($value);
                }
            }
        }
    }
    
    flatten($input_array);
    
    echo"<pre>";
    print_r($output_array);
    echo"</pre>";
    

    输出

    //Input array
    Array
    (
        [0] => Array
            (
                [name] => Parent
                [__children] => Array
                    (
                        [0] => Array
                            (
                                [name] => Child
                            )
    
                        [1] => Array
                            (
                                [name] => Second Child
                            )
    
                    )
    
            )
    
    )
    
    //Output Array
    Array
    (
        [0] => Array
            (
                [name] => Parent
            )
    
        [1] => Array
            (
                [name] => Child
            )
    
        [2] => Array
            (
                [name] => Second Child
            )
    
    )
    

    【讨论】:

      【解决方案3】:

      我最终使用了类似的东西,从@Pankrates 的回答中获得了很多灵感。非常感谢。

      $trees = $multidimensionalArray;
      $flat = array();
      $postRepository->flattenRecursive($flat, $trees);
      //$flat is now a flattened version of $multidimensionalArray
      var_dump($flat);
      
      
      public function flattenRecursive(array &$flat, array $nested, $parentPrepend = false)
      {
          foreach( $nested as $item ){
              $flat[] = array(
                  'name' => ($parentPrepend) ? $parentPrepend . '/' . $item['name'] : $item['name']
              );
              $prepend = $parentPrepend ? $parentPrepend . '/' . $item['name'] : $item['name'];
              if(isset($item['__children']))
                  $this->flattenRecursive($flat, $item['__children'], $prepend);
          }
      }
      

      【讨论】:

        【解决方案4】:

        好的,我试了一下,虽然它可能不是最干净的解决方案,但我认为它应该可以完成工作:

        function flattenRecursive(array &$flat, $parentkey, array $nested){
        
            $flag       = true;
            $prepend    = '';
        
            foreach( $nested as $k => $val ){
                if( is_array($val) ){
        
                    if ( $k == '__children' && $flag) {
                        $prepend = end($flat);
                        $flag = true;
                    } else {
                        $flag = false;
                    }
        
                    flattenRecursive($flat, $prepend , $val);
        
                } else {
        
                    $flat[] = $parentkey . ' ' . $val;
        
                }
            }
        }
        
        function flatten(array $nested){
            $flat = array();
            flattenRecursive($flat, '', $nested);
            return $flat;
        }
        

        在一个测试数组上(额外的嵌套用于额外的测试)如下

        $trees = array(
                    array(
                        'name' => 'Parent',
                        '__children' => array(
                            array(
                                'name' => 'Child',
                                '__children' => array(
                                    array(
                                        'name' => 'Nest One'
                                    ),
                                    array(
                                        'name' => 'Nest Two'
                                    )
                                )
                            ),
                            array(
                                'name' => 'Second Child'
                            )
                        )
                    )
                );
        
        $result = flatten($trees);
        

        $resultvar_dump 如下所示

        array(5) {
          [0]=>
          string(7) " Parent"
          [1]=>
          string(13) " Parent Child"
          [2]=>
          string(22) " Parent Child Nest One"
          [3]=>
          string(22) " Parent Child Nest Two"
          [4]=>
          string(20) " Parent Second Child"
         }
        

        希望这就是你要找的东西

        【讨论】:

        • 嗨,Pankrates,我认为您在这里有所作为。但是,这对我不起作用 b/c 数组比这更复杂,并且使用 foreach( $nested as $k => $val ) 正在扔掉东西。你能把它翻译成使用 foreach( $nested as $item ) 代替吗?
        • 您能否给出一个失败的示例数组以及失败的位置?如果没有示例,很难准确地确定您的意思
        • 看我的回答,再次感谢您的努力!它帮助很大。
        猜你喜欢
        • 2021-01-18
        • 2013-04-01
        • 2020-10-15
        • 1970-01-01
        相关资源
        最近更新 更多