提问者:小点点

多维数组中的部分搜索在深度元素中不起作用


你好我从API得到一个这样的结果:

$data = [
"1" => [
    "book" => "Harry Potter",
    "artist" => array("David", "Emma"),
    "country" => [
        ["description" => "Wander"],
        ["description" => "Magic"]
    ]
],
"2" => [
    "book" => "Science book",
    "artist" => array("Artist 1", "Melanie Hudson"),
    "country" => [
        ["description" => "Physics"],
        ["description" => "Albert Einstein"]
    ]
],
"3" => [
    "book" => "Bible",
    "artist" => array("Artist 1", "Pedro"),
    "country" => [
        ["description" => "Love"],
        ["description" => "Respect"]
    ]
],
];

我正在做的是使用PHP在多维数组中部分搜索一个字符串值。 当我搜索book值(例如Potter)时,它可以工作。 但当涉及到艺术家国家时。 我的密码不管用了。 搜索将返回所有匹配项。 以下是我到目前为止所做的工作:

function searchFor($haystack, $needle)
{
$r = array();
foreach($haystack as $key => $array) {
$contains = false;
foreach($array as $k => $value) {

       if (!is_array($value)) {
           if(stripos($value, $needle) !== false ) {
              $contains = true;
           }
       }

       else {
           searchFor($array['country'],$needle);
       }
  }

   if ($contains) {
      array_push($r,$array);
   }
  }

   return $r;
 }


echo ("<pre>");

print_r(searchFor($data,"Wander"));   <--- Not working. but when I change it to Potter it will work.

echo ("</pre>");

任何想法,我可以如何改进我的代码将非常感谢。 注意:我试图减少使用许多循环和PHP的内置函数。 我只是想要一个简单但有效的解决方案。 希望有人能分享一些想法。 谢谢


共2个答案

匿名用户

下面的逻辑可能会对你有所帮助:

$result = []; // $result is container for matches - filled by reference
$needle = 'Wander'; // the value we are looking for
recurse($data, $needle, $result);

function recurse($haystack = [], $needle = '', &$result) {
    foreach($haystack as $key => $value) {
        if(is_array($value)) {
            recurse($value, $needle, $result);
        } else {
            if(strpos($value, $needle) !== false) {
                $result[] = $value; // store match
            }
        }
    }
}

工作演示

匿名用户

您需要将对searchfor的递归调用的结果与结果$R合并。 在else语句中使用对searchfor的递归调用尝试以下操作:

else {
    $r = array_merge($r, searchFor($array['country'],$needle));
}