简体   繁体   中英

PHP: array filter matching anything containing a string

I have a script which allows me to filter an entire multidimensional array according to a string. But it will only work if a value of the array matches the string exactly while I would like it to work when the string is at least contained in the value.

So, in other words, if the string is "nana", I would like the filtering to let the values "Banana" and "Ananas" be a match. So I would like the search to be done on "%nana%" in order to allow any combination of letters before and after the "nana" string.

Here is my code so far:

$dataset=[[3,"Yellow","Banana"], [2,"Brown","Ananas"], [1,"Green","brown"]];

$dataset = array_filter($dataset, function ($v){
    return filterArray('anana', $v);
});

function filterArray($needle,$haystack){
    $needle = strtolower($needle);

    foreach($haystack as $k => $v){
        $haystack[$k] = strtolower($v);
    };

    return in_array($needle,$haystack);
}

echo '<pre>'; print_r($dataset); echo '</pre>';

This won't work.

I made my homework and found that "fnmatch" or "preg_match" are referenced rather often for this case. The problem is I don't see where they should be in my script. The cases I've browsed are different enough for me not to know how to use them properly here. So it's not about looking the proper function per se but rather about understanding how and where to use it.

I tried this but it didn't work:

....
foreach($haystack as $k => $v){
    if(preg_match('/^'.$needle.'$/i', $v)) {    
        $haystack[$k] = strtolower($v);
    } 
};
....

And this didn't work neither:

....
foreach($haystack as $k => $v){
    if(preg_match("/\b$needle\b/i", $v)) {
        $haystack[$k] = strtolower($v); 
    } 
};
....

I also tried this:

....
$dataset = array_filter(dataset, function ($v){
    return filter((bool)preg_match("/$needle/i",$v);
});
....

None of those changes did any good and it feels to me like I exhausted the solutions found online and in here about this.

I also tried to use "fnmatch", even if I wasn't sure how and where to use it, but with no success.

So any help would be appreciated.

You can use stripos to do a case-insensitive search for the $needle anywhere inside the $haystack value:

$dataset=[[3,"Yellow","Banana"], [2,"Brown","Ananas"], [1,"Green","brown"]];

$dataset = array_filter($dataset, function ($v){
    return filterArray('anana', $v);
});

function filterArray($needle,$haystack){
    foreach($haystack as $v){
        if (stripos($v, $needle) !== false) return true;
    };
    return false;
}

echo '<pre>'; print_r($dataset); echo '</pre>';

Output:

<pre>Array
(
    [0] => Array
        (
            [0] => 3
            [1] => Yellow
            [2] => Banana
        )
    [1] => Array
        (
            [0] => 2
            [1] => Brown
            [2] => Ananas
        )
)
</pre>

Demo on 3v4l.org

You may use stripos to check if a string contains another string.

function filterArray($needle,$haystack){

    foreach($haystack as $k => $v){

        if (stripos($v, $needle) !== false) return true;

    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM