【问题标题】:Partial match search of an array in PHP [duplicate]PHP中数组的部分匹配搜索[重复]
【发布时间】:2014-09-07 06:51:06
【问题描述】:

我正在尝试在多维数组中搜索部分字符串。我的数组如下所示:

$data = array(
    "United Kingdom" => array(
        "AFXX0001" => "Nottingham",
        "AFXX0002" => "Notting Hill",
    ),
    "Germany" => array(
        "ALXX0001" => "Garnottheinem",
        "ALXX0002" => "Tirane",
    ),
);

我正在尝试构建一个搜索功能,该功能将显示满足部分匹配要求的所有结果。到目前为止,我的函数如下所示:

function array_find( $needle, $haystack )
{
    foreach ($haystack as $key => $array) {
        foreach ( $array as $key2 => $value ) {
            if (false !== stripos($needle, $value)) {
                $result = $key . ' ' . $value . ' ' . $key2;
                return $result;
            }
        }
    }
    return false;
}

它有效,但前提是我输入实际值,例如array_find( 'Nottingham', $data );

如果我这样做array_find( 'nott', $data );,我希望它返回诺丁汉、诺丁山和加诺特海内姆,但它却返回bool(false)

【问题讨论】:

  • 即使它确实找到了匹配项,您也只会返回第一个结果,因为您在找到匹配项时返回。我建议查看 array_filter 以使用您自己的比较函数获得多个结果。 stripos 对于部分匹配应该可以正常工作,或者您可以使用某种模糊的“听起来像”功能,例如 levenshtein

标签: php arrays


【解决方案1】:

在您的 stripos() 调用中,您将针和草垛颠倒了。

然后连接结果列表。

试试这个:

function array_find( $needle, $haystack )
{

    $result = '';  //set default value

    foreach ($haystack as $key => $array) {
        foreach ( $array as $key2 => $value ) {
            if (false !== stripos($value,$needle))   // hasstack comes before needle
                {
                $result .= $key . ' ' . $value . ' ' . $key2 . '<br>';  // concat results
                //return $result;
            }
        }
    }

    return $result;
}

【讨论】:

  • stripos() 是不区分大小写的搜索。
【解决方案2】:

行错误:

if (false !== stripos($needle, $value)) {

解决方案:

if (false !== stripos($value, $needle)) {

【讨论】:

    【解决方案3】:
    $data = array(
        "United Kingdom" => array(
            "AFXX0001" => "Nottingham",
            "AFXX0002" => "Notting Hill",
        ),
        "Germany" => array(
            "ALXX0001" => "Garnottheinem",
            "ALXX0002" => "Tirane",
        ),
    );
    $search = 'not';
    
    $result = array();
    array_walk_recursive(
        $data,
        function($item, $key) use ($search, &$result){
            $result[$key] = (stripos($item, $search) !== false) ? $item : null;
        }
    );
    $result = array_filter(
        $result
    );
    var_dump($result);
    

    使用 SPL 迭代器而不是 array_walk_recursive() 的等效项

    $result = array();
    foreach (new RecursiveIteratorIterator(
                 new RecursiveArrayIterator($data),
                 RecursiveIteratorIterator::LEAVES_ONLY
             ) as $key => $value) {
             echo $key,PHP_EOL;
        $result[$key] = (stripos($item, $search) !== false) ? $item : null;
    }
    

    【讨论】:

    • 只做if(stripos($item, $search) !== false){$result[$key] = $item}不是更好吗?这样您就不必使用 array_filter($result) 再次遍历每个值。
    • @imtheman - 很可能,我试图想出一个聪明的解决方案,该解决方案也包括所有级别的密钥,但无法轻松管理,所以就用我所拥有的
    • 我喜欢array_walk_recursive()。我认为这很聪明。我以前从未接触过该功能。
    • @imtheman - 遗憾的是它忽略了本身就是数组的元素(这就是我希望构建嵌套键的方式);我知道它可以使用 SPL 递归迭代器(您只能选择叶子作为选项),但这是一个更复杂的解决方案
    • 哦,我明白了。很有趣。
    猜你喜欢
    • 2013-04-03
    • 2017-05-08
    • 2011-10-22
    • 2013-08-22
    • 2014-06-21
    • 2016-01-02
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多