首页 文章

在数组中反向递归以查找父ID

提问于
浏览
2

试图找出一种获取多维数组中项的父ID的方法:

$Arr = array(
    array(
        "Id" => 1,
        "Parent" => 0,
        "Children" => array(
            array(
                "Id" => 2,
                "Parent" => 1,
                "Children" => array(),
            ),
            array(
                "Id" => 3,
                "Parent" => 1,
                "Children" => array(
                    array(
                        "Id" => 4,
                        "Parent" => 3,
                        "Children" => array(),
                    ),  
                ),
            ),
        ),
    ), 
    array(
        "Id" => 5,
        "Parent" => 0,
        "Children" => array(
            array(
                "Id" => 6,
                "Parent" => 5,
                "Children" => array(),
            ),
        ),
    )
);

我需要获得“父”= 0的顶部元素的“Id” . 对于具有Id 4的项目,它应该返回1作为结果,或者搜索6将返回5.我已经尝试了各种递归函数的方法,但只有在深度为2时才设法获得正确的结果 .

我找到了这个函数,但它似乎返回键的名称而不是值:

function find_parent($array, $needle, $parent = null) {
    foreach ($array as $key => $value) {

        if (is_array($value)) {
            $pass = $parent;
            if (is_string($key)) {
                $pass = $key;
            }
            $found = find_parent($value, $needle, $pass);
            if ($found !== false) {
                return $found;
            }
        } else if ($key === 'Id' && $value === $needle) {
            return $parent;
        }
    }

    return false;
}

编辑

以下仅适用于第1级/深度:

function GetParent($Data = array(), $Needle = 0){
    foreach($Data as $Key => $Item){
        if($Item['Id'] === $Needle && $Item['Parent'] == 0){
            return $Item['Id'];             
        }
        if(sizeof($Item['Children']) !== 0)
            GetParent($Item['Children'], $Item['Parent']);

    }
    return false;
}

我不明白我做错了什么 .

1 回答

  • 3

    虽然它通常不具有速度效率,但PHP在Standard PHP Library (SPL)中有一个非常棒的功能,称为Iterators . Anong他们你可以找到RecursiveArrayIterator,它可以帮助你免于为自己编写递归函数 . 在这种情况下,您必须重新定义其两种方法:

    class CustomRecursiveIterator extends RecursiveArrayIterator
    {
        public function hasChildren() {
            return !empty($this->current()['Children']) && is_array($this->current()['Children']);
        }
    
        public function getChildren()
        {
            return new static($this->current()['Children']);
        }
    }
    

    这样做,您可以确定您将遍历子项,但不是所有数组元素 .

    鉴于此课程,您可以编写适合您需求的功能:

    function getParentId($id, array $array)
    {
        $iterator = new RecursiveIteratorIterator(
            new CustomRecursiveIterator($array),
            RecursiveIteratorIterator::CHILD_FIRST 
        );
    
        $childFound = false;
        foreach ($iterator as $item) {
            if (
                $childFound
                && isset($item['Parent'])
                && $item['Parent'] === 0
                && isset($item['Id'])
            ) {
                return $item['Id'];
            }
    
            if (isset($item['Id']) && $item['Id'] === $id) {
                $childFound = true;
            }
        }
    
        return null;
    }
    

    注意这个标志 RecursiveIteratorIterator::CHILD_FIRST .

    Be aware that this implementation will not work if your array structure is invalid . 例如,如果存在具有给定id的子级,但它没有具有零父级的祖先,则它将返回具有零父级的下一个元素 .

    这是working demo .

相关问题