PHP:从递归数组搜索函数

时间:2016-05-17 15:16:03

标签: 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) {
            $array = $value;
        } elseif (is_array($value)) {
            $this->recursiveArraySearch($needle, $value);
        }
    }

    return $array;
}

这样称呼: $result = $this->recursiveArraySearch('some_index', $configArray);

它无法一次性返回$ result`。

如果$needle$key匹配,那么我只想让它返回值,但此刻它又回归自己。

我还没有实际完成的事情。

由于

UPDATE:当我按照答案建议返回方法并且它到达数组节点的末尾(如二叉树搜索)时,它会传递一个字符串作为$haystack并且因此返回假。

enter image description here

数据结构: 我可能想要将键的值圈起来为红色,或者我可能希望键的值圈出橙色?

该函数需要返回false。

enter image description here

4 个答案:

答案 0 :(得分:3)

你可以这样做

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

答案 1 :(得分:2)

public function recursiveArraySearch($needle, $haystack)
{
    foreach ($haystack as $key => $value) {
        if ($key === $needle) {
            return $value;
        } elseif (is_array($value)) {
            $result = $this->recursiveArraySearch($needle, $value);
            if ($result !== false){
                return $result;
            }
        }
    }

    return false;
}

当您递减时,您需要检查结果并仅在找到项目时返回。如果没有找到任何内容,那么你需要让循环继续。

这假设您的数组不包含任何布尔值。如果是这样,您需要使用其他方法来避免混淆未找到的false值。

答案 2 :(得分:1)

我编辑了this个答案,以满足您的需求。

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

答案 3 :(得分:1)

这里有很多问题。首先,您不是将递归调用返回的数据分配给任何类型的数据结构。此外,您应该更好地检查边缘条件。最后,如果您的Doc Block声明返回了数组,则需要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;
}