【问题标题】:Recursive search function which narrows down results on each iteration递归搜索功能,可缩小每次迭代的结果
【发布时间】:2019-09-29 20:55:54
【问题描述】:

我想编写一个搜索函数,它可以递归地搜索数组并缩小每次迭代的结果。这个想法是它找到第一组结果,然后继续该结果并再次搜索以找到下一组结果。搜索条件以带有指针的数组形式提供。我已经有了一个基本功能,但结果不如预期。

我已经编写了正在工作的递归函数。然而,迭代并没有给我最终的结果。

$array = array(
    0 => array('id' => 1, 'currency' => 'EUR', 'name' => 'NL', 'country_code' => 31), 
    1 => array('id' => 2, 'currency' => 'EUR', 'name' => 'DE', 'country_code' => 49),
    2 => array('id' => 3, 'currency' => 'EUR', 'name' => 'FR', 'country_code' => 33),
    3 => array('id' => 4, 'currency' => 'EUR', 'name' => 'BE', 'country_code' => 32),
    4 => array('id' => 5, 'currency' => 'USD', 'name' => 'US', 'country_code' => 1),
    5 => array('id' => 6, 'currency' => 'Rand', 'name' => 'SAF', 'country_code' => 27),
    6 => array('id' => 7, 'currency' => 'Rubbles', 'name' => 'RUS', 'country_code' => 7),
    7 => array('id' => 8, 'currency' => 'EUR', 'name' => 'IT', 'country_code' => 39),
    8 => array('id' => 9, 'currency' => 'Pound', 'name' => 'GB', 'country_code' => 44),
); //list of countries which needs to searched

$query = array('currency' => 'EUR', 'id' => 8, 'country_code' => 49); //search needles

function _searchData(array $array, array $query, $counter=0) 
{
  $result = array();
  $matches_found = array();

  if($array){
     $i = $counter; //set counter, start with 0
     $keys = array_keys($query); //get query keys
     $vals = array_values($query); //get query values
     $max = count($keys); //set max_count to limit iteration

     foreach($array as $arrkey => $arrval){
       if(isset($arrval[$keys[$i]]) && $arrval[$keys[$i]] == $vals[$i] && $i < $max){ 
         $matches_found = $this->_searchData($arrval, $query, $i++); //return result, increment counter
         if($matches_found){    
           $arrval = $matches_found; //overwrite result array           
          }
       $result[] = $arrval;  
     }
   }
  return $result;
}
Expected result = 
**it should fail on the 3rd iteration because "country_code" does not match 
on result id 8.  

我认为我的主要问题是计数器,因为它需要增加。在 foreach 循环中,我无法完全控制。我已经尝试存储matches_found并在循环外重新使用它,但这也不起作用。

该函数的目标是缩小每次迭代的结果,以最终得到一组结果,因为它匹配更少的键值对。 Ps 也许有一种更简单的方法来搜索带有大量针的数组,我总是愿意接受其他建议,但我的主要目标是让这个递归函数运行起来,因为它对我来说最有意义来实现我想要的结果。同样在灵活性方面,我可以根据需要拥有尽可能多的搜索针。我希望有人能让我朝着正确的方向前进。提前致谢!

【问题讨论】:

  • 你能把输入数组和预期输出数组放到你的问题上吗?没有它,我们不知道您在描述的数组中搜索什么。
  • 您好 CodiMech25,感谢您的快速回复。我添加了需要搜索的主数组。感谢您查看我的问题。
  • 不知道你想在这里用递归来完成什么,但我已经看到你的代码中有一个可疑的部分。进入另一个级别的递归时,您应该将参数传递为$i + 1 而不是$i++
  • 您好 Ultimater,感谢您的建议。我已经测试过了。计数器正确递增,但尚未达到预期结果。基本上我希望该功能缩小结果范围,因此它以例如开头5 个结果,因为它找到 'currency' => 'EUR',然后将该数组发送回函数,根据 'id' => 8 搜索下一组结果,最终结果为 1 个。我想添加尽可能多的搜索值,因为它循环,它缩小了结果。希望这是有道理的。谢谢!

标签: php function recursion search


【解决方案1】:

我认为根据您的要求,您可以做很多简单的事情,例如:

<?php

$in = [
    ['id' => 1, 'currency' => 'EUR',     'name' => 'NL'],
    ['id' => 2, 'currency' => 'EUR',     'name' => 'DE'],
    ['id' => 3, 'currency' => 'EUR',     'name' => 'FR'],
    ['id' => 4, 'currency' => 'EUR',     'name' => 'BE'],
    ['id' => 5, 'currency' => 'USD',     'name' => 'US'],
    ['id' => 6, 'currency' => 'Rand',    'name' => 'SAF'],
    ['id' => 7, 'currency' => 'Rubbles', 'name' => 'RUS'],
    ['id' => 8, 'currency' => 'EUR',     'name' => 'IT'],
    ['id' => 9, 'currency' => 'Pound',   'name' => 'GB'],
];

$query = ['currency' => 'EUR', 'id' => 8]; //search needles

// array_filter will use the given callback to check every entry
$out = array_filter($in, function(array $candidate) use ($query) {
    // iterate over query
    foreach ($query as $key => $predicate) {
        // if the key exists, but the value differs
        if (isset($candidate[$key]) && $candidate[$key] !== $predicate) {
            // it should not be included
            return false;
        }
    }

    // otherwise, include
    return true;
});

print_r($out);

演示:https://3v4l.org/aAZPP

参考:https://www.php.net/manual/function.array-filter.php

【讨论】:

  • 嗨,Yoshi,感谢您的回答。同意这看起来要简单得多。我只有在开始添加第三根针时才会遇到问题。如果它匹配第二根针而第三根针失败,它​​仍然会被包含为一个好的结果。所以这并不是我们想要的结果。我将更新我的输入数组,因为它有更多的值,我只是把它修整了,所以它更容易阅读。一会儿……
  • @DFA 我不确定我是否理解。给定您的新输入,代码会给出一个空数组作为结果。这是意料之中的,因为没有条目符合所有要求?
  • 对不起,我的错误,我使用了错误的输入数组。我现在看到它工作了,谢谢!会接受这个作为正确答案。
  • Yoshi,我想问一下,当我使用整数时它会返回结果,当使用数字字符串时它不会?这是 array_filter 的预期行为吗?对不起我的菜鸟问题。谢谢。
  • 修复它使用:$query = array_map('strval', $query);现在按预期工作。谢谢!
猜你喜欢
  • 2014-05-05
  • 1970-01-01
  • 2018-09-20
  • 2017-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多