【问题标题】:Recursive array search returns reference of sub array?递归数组搜索返回子数组的引用?
【发布时间】:2014-01-07 03:13:45
【问题描述】:

我有一个变量,$nav。

我有一个函数将返回$nav 的子数组。

我想编辑这个子数组作为对$nav的引用。

这是我用来执行此操作的代码,并带有一些测试代码以查看引用是否有效:

$group =& $this->find($parent, $this->nav);

$group['group'] = 'group'; // NOT a reference

private function find($needle, &$haystack) {

    $haystack['haystack'] = 'haystack'; // still a reference

    foreach ($haystack as &$sel) {

        $sel['sel'] = 'sel'; // BOTH a reference and not??

        if ($sel['link']->getSlug() == $needle)
            return $sel;

    }

}

这里是 var 转储:

$group转储:

Array
(
    [link] => Link Object
        (
            [text:Link:private] => root
            [slug:Link:private] => root
            [url:Link:private] => /root
        )

    [sel] => sel
    [group] => group
)

$nav转储:

Array
(
    [0] => Array
        (
            [link] => Link Object
                (
                    [text:Link:private] => root
                    [slug:Link:private] => root
                    [url:Link:private] => /root
                )

            [sel] => sel
        )

    [haystack] => haystack
)

为数组设置测试值表明操作$haystack 正在影响对$nav 的引用。在 foreach 循环中编辑 $sel 变量既是引用又不是引用(为什么?)。编辑$group变量显示引用没有通过。

回答 为了让它工作,我需要将 foreach 变量设置为一个引用,并在函数find() 中声明一个返回引用。这是正确的代码:

$group =& $this->find($parent, $this->nav);

// edit `$group` here, which will edit 
// the returned reference of the sub-array of `$this->nav`

private function &find($needle, &$haystack) {

foreach ($haystack as &$sel) {

    if ($sel['link']->getSlug() == $needle)
        return $sel;

}

【问题讨论】:

  • 你有没有一个例子说明你的数组$nav/$group在函数之前和之后应该是什么样子?一旦在你的函数中,我看不到你在哪里实际作用于任何变量。我也不明白为什么需要通过引用传入数组。您始终可以对函数中的数组进行操作,然后在完成后返回被操作的数组。也许我不明白你到底想做什么。
  • 当然,我将编辑我的帖子以显示我要对数组执行的操作。
  • 出于好奇,如果$group给了你想要的东西,是不是有什么原因你不能用??
  • 如果我能把它轻松放入$nav,我完全可以接受。但我希望它有无限数量的子阵列。所以我不确定如何找到在哪里弹出$group。
  • 明白了。到目前为止,我可以告诉您的一件事是,要通过引用进行分配,您需要将 & 符号与赋值运算符一起使用。 $group = &$this->find($parent, $this->nav); 应该是 $group =& $this->find($parent, $this->nav);

标签: php arrays recursion reference pass-by-reference


【解决方案1】:

请原谅,我仍然对您想要达到的目标感到有些困惑。但是,查看您的代码,您传入$this->nav 作为参考(看起来很好而且花哨),但在您的函数内部,我看不到$this->nav(现在是$haystack)实际上是在哪里被操纵的。同样在 foreach 循环中,您正在使用的值需要作为引用传递,以便对其进行操作。

所以你当前的代码是:

private function find($needle, &$haystack) { //$haystack points to $this->nav
  foreach ($haystack as $sel) {  //$sel is a copy of the value in $this->nav not a reference
    if (isset($sel['sub']))
      $this->find($needle, $sel['sub']);
    if ($sel['link']->getSlug() == $needle)
      return $sel;
  }
}

因此,您的 $this->nav 数组实际上根本没有被操纵。如果您修改您的foreach 以使用引用,那么可能会有所帮助。

foreach($haystack as &$sel)

这将导致$sel 引用$haystack 中的实际值(而不是复制它),并且由于$haystack 已经是一个引用,您应该使用您的$this->nav 变量.

如果之后事情变得过于模糊,您可能希望重新考虑一下您的实施。

【讨论】:

  • 我已经编辑了我的原始帖子以更清晰。你对 foreach 的看法是对的,它现在正在工作(虽然对我来说很奇怪 - 作为参考而不是作为参考)。编辑:我最初并没有计划在 find 函数中实际编辑任何内容,我希望它基本上返回我将放置新子数组的数组。也许你是对的,我应该重新考虑实施。
  • 啊哈!我曾经对您进行了更正,为了让$group 作为参考,我需要在函数声明前添加与号。
  • 很高兴听到你的消息,很高兴你的事情进展顺利!
【解决方案2】:

听起来您想要做的是存储对 $nav 数组元素的引用。如果是这种情况,那么这应该工作:

private function find($needle, &$haystack) {
  foreach ($haystack as &$sel) {
    if (isset($sel['sub']))
      $this->find($needle, $sel['sub']);
    if ($sel['link']->getSlug() == $needle)
      return &$sel;
  }
}

你需要通过引用将你想要的数组传递给函数,然后在foreach中指定该元素是一个引用,然后返回对该元素的引用,否则php会自动获取引用所引用的值并存储它在一个新的内存块中。

【讨论】:

    猜你喜欢
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    相关资源
    最近更新 更多