【问题标题】:Reverse recursive in array to find parent id在数组中反向递归以查找父ID
【发布时间】:2017-03-23 06:53:40
【问题描述】:

试图找出一种在多维数组中获取项目的父 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(),
            ),
        ),
    )
);

我需要获取“Parent”= 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;
}

编辑

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

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;
}

我不明白我做错了什么。

【问题讨论】:

  • 而不是遍历所有键,你不只是检查子值像if ($arr['Id'] == $needle) { return $arr['Parent']; }
  • 你要返回什么?
  • @Duvdevan:我想返回父元素的“Id”值。如果搜索 6,则该函数应返回 5,如果搜索 4,则应返回 1。

标签: php recursion multidimensional-array parent


【解决方案1】:

虽然它通常不具有速度效率,但 PHP 在 Standard PHP Library (SPL) 中有一个非常棒的特性,称为 Iterators。在它们中,您可以找到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。

请注意,如果您的数组结构无效,此实现将不起作用。例如,如果有一个给定 id 的子元素,但它没有父元素为零的祖先,它将返回下一个父元素为零的元素。

这里是working demo。

【讨论】:

  • 非常棒,可读而不是意大利面!我正在为这个答案添加书签!
  • @sevavietl 谢谢!但就像你说的,我必须调整我的调用来处理零父母。
猜你喜欢
  • 2020-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 1970-01-01
  • 2015-12-18
  • 1970-01-01
相关资源
最近更新 更多