2016-05-17 159 views
0
返回

所以我有这个(简单的)方法:PHP:从递归阵列搜索功能

/** 
* @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并因此返回false一个字符串。

enter image description here

数据结构: 我可能想获得关键的价值盘旋红色或我可能要在关键的价值盘旋橙色?

该函数需要返回false。

enter image description here

+1

在递归分支中,你没有对从递归调用返回的值进行任何操作(即将其添加到正在构建的数组中),可以说明您打算返回到哪种数据结构初始呼叫者谁初始呼叫此方法? –

+0

@MikeBrant我更新了问题的数据结构。 – Kal

+1

@凯我不清楚是否你想返回所有匹配或第一次匹配。这两个用例,因为它似乎接受的答案只涵盖用于查找单个匹配的用例 –

回答

1
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值混淆。

+0

美丽。这样做的窍门,知道有一些简单的我错过了。 – Kal

+0

这是不正确的。您不希望简单地返回递归搜索的结果而不将其追加到现有匹配结果。这是除非你只想返回匹配键的第一个找到的值。我猜测这是因为OP设想返回一组结果而不是cass。 –

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

查看更新:) – Kal

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

查看更新:) – Kal

+0

@Kal我编辑了我的答案。现在该函数只有在找不到键时才返回false。 –

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