我想编写一个搜索函数,该函数可以递归搜索数组并缩小每次迭代的结果。想法是找到第一组结果,然后继续该结果,然后再次搜索以找到下一组结果。搜索条件以带针的数组形式提供。我已经有一个基本的功能,但结果不符合预期。
我已经编写了运行的递归函数。但是迭代并没有给我我最终的结果。
$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循环中,我无法完全控制。我尝试存储matchs_found并在循环外重新使用它,但这也不起作用。
该函数的目标是缩小每次迭代的结果,以最终结果集结尾,因为它与较少的键值对匹配。 Ps也许有一种更简单的方法来搜索带有大量指针的数组,而且我总是愿意接受其他建议,但是我的主要目标是使此递归函数正常运行,因为这对我来说最有意义的是实现我的期望结果。同样,在灵活性方面,我可以根据需要拥有任意数量的搜索针。我希望有人能给我正确的方向。预先感谢!
答案 0 :(得分:2)
我认为您可以根据自己的要求做很多简单的事情,例如:
<?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);