从节点树数组获取父节点

时间:2019-11-14 01:53:47

标签: php recursion 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
      }
    ]
  }
]

假设我在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);
        }
    }
}

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

我最终编写了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);