【问题标题】:Getting all children for a deep multidimensional array获取深度多维数组的所有孩子
【发布时间】:2012-01-29 05:04:46
【问题描述】:

我有这样的数组:

array(
    array(
        'id' => 1,
        'children' => array(
            array(
                'id' => 2,
                'parent_id' => 1
            ),
            array(
                'id' => 3,
                'parent_id' => 1,
                'children' => array(
                    array(
                        'id' => 4,
                        'parent_id' => 3
                    )
                )
            )
        )
    )
);

如果有必要,数组会更深。我需要获取任何给定 ID 的孩子。

谢谢。

【问题讨论】:

    标签: php arrays recursion multidimensional-array iterator


    【解决方案1】:
    function getChildrenOf($ary, $id)
    {
      foreach ($ary as $el)
      {
        if ($el['id'] == $id)
          return $el;
      }
      return FALSE; // use false to flag no result.
    }
    
    $children = getChildrenOf($myArray, 1); // $myArray is the array you provided.
    

    除非我遗漏了某些东西,否则遍历数组以查找与 id 键和您正在寻找的 id 匹配的东西(然后将其作为结果返回)。您还可以迭代搜索(并给我一秒钟的时间来发布代码,这将检查 parentId 键)...

    --

    递归版本,包括子元素:

    function getChildrenFor($ary, $id)
    {
      $results = array();
    
      foreach ($ary as $el)
      {
        if ($el['parent_id'] == $id)
        {
          $results[] = $el;
        }
        if (count($el['children']) > 0 && ($children = getChildrenFor($el['children'], $id)) !== FALSE)
        {
          $results = array_merge($results, $children);
        }
      }
    
      return count($results) > 0 ? $results : FALSE;
    }
    

    递归版本,不包括子元素

    function getChildrenFor($ary, $id)
    {
      $results = array();
    
      foreach ($ary as $el)
      {
        if ($el['parent_id'] == $id)
        {
          $copy = $el;
          unset($copy['children']); // remove child elements
          $results[] = $copy;
        }
        if (count($el['children']) > 0 && ($children = getChildrenFor($el['children'], $id)) !== FALSE)
        {
          $results = array_merge($results, $children);
        }
      }
    
      return count($results) > 0 ? $results : FALSE;
    }
    

    【讨论】:

    • 它需要递归,因为数组可以更深
    • @Topener:问题在回答中被更改,所以我正在修复以适应。 -- cnkt: 工作中,给我一分钟左右。
    • 我改变了问题,因为人们不喜欢 var_dump 输出 :)
    • 这个函数只检查第一层。如果 id 与您要找的不匹配,您需要检查孩子们。类似[...] return $el; else return getChildrenOf($el, $id);
    • @cnkt:如果你想保持层次结构,试试这个:ideone.com/5ovbW(否则我可以修复删除任何孩子)——编辑:这是没有children键的更新: ideone.com/rusFS
    【解决方案2】:
    function array_searchRecursive( $needle, $haystack, $strict=false, $path=array() )
    {
        if( !is_array($haystack) ) {
            return false;
        }
    
        foreach( $haystack as $key => $val ) {
            if( is_array($val) && $subPath = array_searchRecursive($needle, $val,     $strict, $path) ) {
                $path = array_merge($path, array($key), $subPath);
                return $path;
            } elseif( (!$strict && $val == $needle) || ($strict && $val['id'] === $needle) ) {
                $path[] = $key;
                return $path;
            }
        }
        return false;
    }
    
    array_searchRecursive( 5, $arr );
    

    -- 参考:http://greengaloshes.cc/2007/04/recursive-multidimensional-array-search-in-php/

    【讨论】:

    【解决方案3】:

    一种天真的方法是通过从根开始遍历树直到找到节点来做一个详尽的search on the tree。在最坏的情况下,您必须迭代整个树,只注意您要查找的节点是最后一个节点,或者甚至不存在。

    更好的方法是首先构建一个索引,将 ID 映射到树内的节点上。有了这个,您只需要遍历整个树一次,然后就可以通过索引直接访问节点。理想情况下,索引将在从平面数据构建树结构期间完成。

    所以如果你有一个像your other question 这样的平面数组,你可以通过平面数组的一次迭代来构建树和索引:

    // array to build the final hierarchy
    $tree = array(
        'children' => array()
    );
    
    // index array that references the inserted nodes
    $index = array(0=>&$tree);
    
    foreach ($arr as $key => $val) {
        // pick the parent node inside the tree by using the index
        $parent = &$index[$val['parent_id']];
        // append node to be inserted to the children array
        $node = $val;
        $parent['children'][$val['id']] = $node;
        // insert/update reference to recently inserted node inside the tree
        $index[$val['id']] = &$parent['children'][$val['id']];
    }
    

    此代码取自my answer to a similar question。您发布的最后一个数组位于$tree['children']。然后可以使用$index[12345] 访问其中的每个节点。

    【讨论】:

      【解决方案4】:

      您可以为此使用内置代码

      $iter = new RecursiveIteratorIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::SELF_FIRST);
      foreach ($iter as  $val) {
          if (isset($val['id']) && $val['id'] === 3) {
              print_r($val['children']);
              break;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-08-28
        • 2023-03-25
        • 1970-01-01
        • 2019-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-31
        • 2021-08-19
        相关资源
        最近更新 更多