PHP:从递归数组搜索函数返回

PHP:从递归数组搜索函数返回,php,arrays,function,recursion,Php,Arrays,Function,Recursion,所以我有一个简单的方法: /** * @param $needle * @param $haystack * * @return array */ public function recursiveArraySearch($needle, $haystack) { $array = false; foreach ($haystack as $key => $value) { if ($key === $needle) {

所以我有一个简单的方法:

/**
 * @param       $needle
 * @param       $haystack
 *
 * @return array
 */
public function recursiveArraySearch($needle, $haystack)
{
    $array = false;

    foreach ($haystack as $key => $value) {
        if ($key === $needle) {
            $array = $value;
        } elseif (is_array($value)) {
            $this->recursiveArraySearch($needle, $value);
        }
    }

    return $array;
}
这就是所谓的: $result=$this->recursiveArraySearch'some_index',$configArray;

它很难一次性将其返回到$result`

如果$pinder与$key匹配,那么我只希望它返回值,但此时它正在返回自身

一些我还没有真正做过的事情

谢谢

更新:当我按照答案返回方法时,它到达数组节点的末尾,就像二叉树搜索一样,它将一个字符串作为$haystack传入,因此返回false

数据结构: 我可能想要红色圆圈键的值,或者想要橙色圆圈键的值

函数需要将它们返回为false

你可以这样做

  public function recursiveArraySearch($needle, $haystack)
{
    foreach ($haystack as $key => $value) {
        if ($key === $needle) {
            return $value;
        } elseif (is_array($value)) {
            $check = $this->recursiveArraySearch($needle, $value);
            if($check)
               return $check;
        }
    }
return false;
}
我编辑了答案以满足您的需要

function findKey($array, $keySearch)
{
    foreach ($array as $key => $item) {
        if ($key == $keySearch) {
            return $item;
        }
        else {
            if (is_array($item)) {
                $keyFound = findKey($item, $keySearch);
                if( $keyFound != false ) {
                    return $keyFound;
                }
            }
        }
    }
    return false;
}
当您向下递归时,您需要检查结果并仅在找到项时返回。如果没有找到任何内容,则需要让循环继续


这假定数组不包含任何布尔值。如果是这样,您需要使用另一种方法来避免混淆not found的假值。

这里有许多问题。首先也是最重要的是,您没有将递归调用返回的数据分配给任何类型的数据结构。此外,您应该在检查边缘条件方面做得更好。最后,如果您的Doc块显示返回了数组,则需要100%确保您返回的是数组。这是您在调用者阅读有关此方法的文档时与他们签订的合同,因此您应该遵守该合同

下面的示例假设您只是将数值索引的值数组返回给初始调用方。此示例包括将递归结果合并到活动数组,更好地处理输入验证,以及使用空数组一致返回数字索引数组,表示没有结果

/**
 * @param mixed $needle Integer or string key value used for recursive search.
 * @param array $haystack Array to be searched.
 *
 * @throws InvalidArgumentException
 *
 * @return array Return numerically-indexed array with empty array if no match.
 */
public function recursiveArraySearch($needle, array $haystack)
{
    // validate that we have a proper needle passed
    if(!is_int($needle) && !is_string($needle)) {
       throw new InvalidArgumentException(
           'Invalid search needle type passed as argument. ' .
           "Integer or string value expected. Value passed:\n" .
           var_export($needle, true)
       );
    }

    $array = [];
    foreach ($haystack as $key => $value) {
        // recursively search if $value is non-empty array
        if(is_array($value) && !empty($value)) {
            array_merge($array, $this->recursiveArraySearch($needle, $value));
        }
        // otherwise, we can make exact string/integer comparison
        else if ($key === $needle) {
            $array[] = $value;
        }
    }

    return $array;
}
请注意,我假设您正在查找递归结构中的所有匹配项。如果您正在寻找第一个匹配项,可以执行以下操作,即广度优先搜索

/**
 * @param mixed $needle Integer or string key value used for recursive search.
 * @param array $haystack Array to be searched.
 *
 * @throws InvalidArgumentException
 *
 * @return mixed Return values could be mixed since we have no constraint on 
 *    value types in haystack.  Null will be returned on no match, thus 
 *    this function cannot differentiate explicitly defined null values
 *    from no match.
 */
public function recursiveBreadthFirstSingleMatchArraySearch($needle, array $haystack)
{
    // validate that we have a proper needle passed
    if(!is_int($needle) && !is_string($needle)) {
       throw new InvalidArgumentException(
           'Invalid search needle type passed as argument. ' .
           "Integer or string value expected. Value passed:\n" .
           var_export($needle, true)
       );
    }

    // see if there is key match at first level of array
    if(array_key_exists($needle, $haystack)) {
        return $haystack[$needle];
    }

    // iterate through haystack performing recursive search on array until match
    foreach ($haystack as $key => $value) {        
        // recursively search if $value is non-empty array
        if(is_array($value) && !empty($value)) {
            $result = $this->
                recursiveBreadthFirstSingleMatchArraySearch($needle, $value));
            if (!is_null($result)) {
                return $result;
            }
        }
    }

    return null;
}

@我编辑了我的答案。现在,函数只在找不到键时返回false。在递归分支中,您没有对递归调用返回的值执行任何操作,即将其添加到正在生成的数组中。您能说明您打算返回给发起此方法初始调用的主调用方的数据结构吗?@MikeBrant我用数据结构更新了问题。@Kai我不清楚您是要返回所有匹配项还是第一个匹配项。我已经添加了涵盖这两个用例的答案,因为它似乎只涵盖了查找单个匹配的用例。我知道我遗漏了一些简单的东西,这是不对的。您不希望只返回递归搜索的结果,而不将其附加到现有匹配结果中。除非您只想返回与键匹配的第一个找到的值。我猜这不是cass,因为OP设想返回一系列结果。
/**
 * @param mixed $needle Integer or string key value used for recursive search.
 * @param array $haystack Array to be searched.
 *
 * @throws InvalidArgumentException
 *
 * @return mixed Return values could be mixed since we have no constraint on 
 *    value types in haystack.  Null will be returned on no match, thus 
 *    this function cannot differentiate explicitly defined null values
 *    from no match.
 */
public function recursiveBreadthFirstSingleMatchArraySearch($needle, array $haystack)
{
    // validate that we have a proper needle passed
    if(!is_int($needle) && !is_string($needle)) {
       throw new InvalidArgumentException(
           'Invalid search needle type passed as argument. ' .
           "Integer or string value expected. Value passed:\n" .
           var_export($needle, true)
       );
    }

    // see if there is key match at first level of array
    if(array_key_exists($needle, $haystack)) {
        return $haystack[$needle];
    }

    // iterate through haystack performing recursive search on array until match
    foreach ($haystack as $key => $value) {        
        // recursively search if $value is non-empty array
        if(is_array($value) && !empty($value)) {
            $result = $this->
                recursiveBreadthFirstSingleMatchArraySearch($needle, $value));
            if (!is_null($result)) {
                return $result;
            }
        }
    }

    return null;
}