【问题标题】:get parent nodes from a node tree array从节点树数组中获取父节点
【发布时间】:2019-11-14 01:53:47
【问题描述】:
[
  {
    "id": 1573695284631,
    "name": "Cars",
    "pid": 0,
    "children": [
      {
        "id": 1573695292010,
        "name": "Audi",
        "pid": 1573695284631
      },
      {
        "id": 1573695305619,
        "name": "BMW",
        "pid": 1573695284631,
        "children": [
          {
            "id": 1573695328137,
            "name": "3 Series",
            "pid": 1573695305619
          },
          {
            "id": 1573695335102,
            "name": "X5",
            "pid": 1573695305619
          }
        ]
      }
    ]
  },
  {
    "id": 1573695348647,
    "name": "Motorcycles",
    "pid": 0,
    "children": [
      {
        "id": 1573695355619,
        "name": "Ducatti",
        "pid": 1573695348647
      }
    ]
  }
]

假设我在 PHP 中有这个类似节点树的数组(为了便于阅读,上面用 json 表示)。对于给定的子节点 ID,我想找到它嵌套的所有父节点 ID。例如,

getParentNodes($haystack, $child_node_id=1573695328137); //[1573695284631, 1573695292010, 1573695305619]

我认为这是递归的一个用例。这是我最好的尝试:

function getParentNodes($haystack, $child_node_id) {

    if( empty($haystack->children) )
        return;

    foreach($haystack->children as $child) {
        if($child->id == $child_node_id) {
            // $child found, now recursively get parents
        } else {
            getParentNodes($child, $child_node_id);
        }
    }
}

【问题讨论】:

    标签: php recursion tree


    【解决方案1】:

    这个将遍历树,直到它达到所需的 id。 在叶子不是所需叶子的所有情况下,它将返回 false - 如果找到孩子,则折叠堆栈导致 false 或父 ID 数组。

    代码

    function getParentNodes($haystack, $child_node_id) {
        foreach ($haystack as $element) {
            if ($element['id'] === $child_node_id) {
                // return [$element['id']]; // uncomment if you want to include child itself
                return [];
            } else if (array_key_exists('children', $element)) {
                $parentNodes = getParentNodes($element['children'], $child_node_id);
                
                if ($parentNodes !== false) {
                    return [$element['id'], ...$parentNodes];
                }
            }
        }
        
        return false;
    }
    

    输出父 ID:

    array(2) {
      [0]=>
      int(1573695284631)
      [1]=>
      int(1573695305619)
    }
    

    工作example

    【讨论】:

      【解决方案2】:

      您缺少返回结果。这就是你想要的。

      function getParentNodes($arr, $child_node_id) {
      
          $result = [];
      
          foreach($arr as $item) {
      
              if($item->pid == $child_node_id) {
                  $result[] = $item->id;
              }
      
              if(!empty($item->children)) {
                  $result[] = getParentNodes($item->children, $child_node_id);
              }
      
          }
      
          return $result;
      }
      

      您还需要将值作为平面数组获取

      $values = getParentNodes($values, 1573695284631);
      
      // do flat arr
      array_walk_recursive($values,function($v) use (&$result){ $result[] = $v; });
      
      // your values
      var_dump($result);
      

      Source reference for flat array

      【讨论】:

      • 谢谢,但这不会让我走得太远。最困难的部分是得到父母
      【解决方案3】:

      我最终写了 2 个递归函数

      function treeSearch($needle, $haystack) {
          foreach($haystack as $node) {
              if($node->id == $needle) {
                  return $node;
              } elseif ( isset($node->children) ) {
                  $result = treeSearch($needle, $node->children);
                  if ($result !== false){
                      return $result;
                  }
              }
          }
      
          return false;
      }
      

      treeSearch会在树中找到节点,然后我需要递归上树,直到父id(pid)为0

      function getParents($node, $hierarchy, $all_parent_ids=[]) {
          if($node->pid != 0) {
              $parent_node = treeSearch($node->pid, $hierarchy);
              $all_parent_ids[] = $parent_node->id;
              $result = getParents($parent_node, $hierarchy, $all_parent_ids);
      
              if ($result !== false){
                  return $result;
              }
          }
      
          return $all_parent_ids;
      }
      

      那么,假设这棵树被称为 $tree 我可以这样称呼它们:

      $node = treeSearch(1573695328137, $tree);
      $parents = getParents($node, $tree);
      
      

      【讨论】:

        【解决方案4】:

        这是获取孩子父母最佳解决方案!

        function getPathParent($id, $tree='',$opts='', &$path = array()) {
            $in = array_replace(array(
                'id'=>'id',
                'child'=>'children',
                'return'=>'id'
            ),(array)$opts);
            if ( is_array($tree) && !empty($tree) ){
                foreach ($tree as $item) {
                    if ($item[$in['id']] == $id) {           
                        array_push($path, $item[$in['return']]);
                        return $path;
                    }
                    if ( isset($item[$in['child']]) && !empty($item[$in['child']]) ) {
                        array_push($path, $item[$in['return']]);
                        if (getPathParent($id, $item[$in['child']],$opts, $path) === false) {
                            array_pop($path);
                        } else {
                            return $path;
                        }
                    }
                }
            }
            return false;
        }
        
        
        $tree = [
            [
                "id" => 1573695284631,
                "name" => "Cars",
                "pid" => 0,
                "children" => [
                    [
                        "id" => 1573695292010,
                        "name" => "Audi",
                        "pid" => 1573695284631
                    ],
                    [
                        "id" => 1573695305619,
                        "name" => "BMW",
                        "pid" => 1573695284631,
                        "children" => [
                            [
                                "id" => 1573695328137,
                                "name" => "3 Series",
                                "pid" => 1573695305619
                            ],
                            [
                                "id" => 1573695335102,
                                "name" => "X5",
                                "pid" => 1573695305619
                            ]
                        ]
                    ]
                ]
            ],
            [
                "id" => 1573695348647,
                "name" => "Motorcycles",
                "pid" => 0,
                "children" => [
                    [
                        "id" => 1573695355619,
                        "name" => "Ducatti",
                        "pid" => 1573695348647
                    ]
                ]
            ]
        ];
        
        
        $getParentNode = getPathParent(1573695335102,$tree);
        var_export($getParentNode);
        // return: 
        /*
        array (
          0 => 1573695284631,
          1 => 1573695305619,
          2 => 1573695335102,
        )
        */
        $getParentNode = getPathParent(1573695335102,$tree,array('return'=>'name'));
        var_export($getParentNode);
        // return: 
        /*
        array (
          0 => 'Cars',
          1 => 'BMW',
          2 => 'X5',
        )
        */
        $getParentNode = getPathParent(1573695335102,$tree,array('id'=>'id','child'=>'children','return'=>'pid'));
        var_export($getParentNode);
        // return: 
        /*
        array (
          0 => 0,
          1 => 1573695284631,
          2 => 1573695305619,
        )
        */
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多