多个array_filter和strpos

时间:2019-01-05 08:27:26

标签: php strpos array-filter

我想返回不包含字符列表的数组。

下面的代码对于一个关键字('bc')来说效果很好。

$array = array("abc", "def", "ghi");
$filterArray = array_filter($array, function ($var) {return(strpos($var, 'bc') === false);});
print_r($filterArray);

但是,当我尝试使用$excludeKeyword_arrforeach筛选出多个关键字时,以下代码不起作用。

$array = array("abc", "def", "ghi");
$excludeKeyword_arr = ("ab", "de");
foreach($excludeKeyword_arr as $exclude){
    $filterArray = array_filter($array, function ($var) {return(strpos($var, $exclude) === false);});
}
print_r($filterArray);

它应该是返回数组,而不是布尔类型。

4 个答案:

答案 0 :(得分:1)

代码有2个问题。首先是$exclude的范围不允许闭包访问它,只需将其与use一起传递即可解决。

第二个问题是,您始终过滤原始数组($array),因此无法达到累积效果。所以在这里,我复制数组并继续过滤副本($filterArray = array_filter($filterArray, function)...

$array = array("abc", "def", "ghi");
$excludeKeyword_arr = array("ab", "de");
$filterArray = $array;
foreach($excludeKeyword_arr as $exclude){
    $filterArray = array_filter($filterArray, function ($var) use ($exclude) 
                     {return(strpos($var, $exclude) === false);});
}
print_r($filterArray);

结果

Array
(
    [2] => ghi
)

答案 1 :(得分:1)

您可以使用preg_grep进行相反的操作,并匹配具有bcde然后是array_diff的对象。

$array = array("abc", "def", "ghi");
$excludeKeyword_arr = array("bc", "de");
$exclude_values = preg_grep("/". implode("|", $excludeKeyword_arr) . "/", $array);
$filterArray = array_diff($array, $values_with_bc);

print_r($filterArray); // [ 2 => "ghi"]

https://3v4l.org/IpNal

答案 2 :(得分:0)

为了获得最佳性能,请使用带有条件foreach()的{​​{1}}循环-这样,php不需要执行无用的迭代。

如果子字符串在干草堆字符串的任何位置都可以找到,请使用break将其从干草堆数组中删除。

代码:(Demo

unset()

输出:

$array = ["abc", "def", "ghi"];
$excludeKeyword_arr = ["ab", "de"];

foreach ($array as $index => $haystack) {
    foreach ($excludeKeyword_arr as $needle) {
        if (strpos($haystack, $needle) !== false) {
            unset($array[$index]);
            break;
        }
    }
}
var_export(array_values($array));

请注意:如果为了简洁起见而接受array ( 0 => 'ghi', ) 的调用概念,请理解,出于可靠性/稳定性的考虑,必须将preg_应用于needles数组中的每个值(如果有)对正则表达式引擎具有特殊含义的字符的机会。

答案 3 :(得分:0)

我会做与@Andreas相同的操作,但最后会重新索引。

$array           = ["ab", "def", "ghi"];
$excludeKeywords = ["ab", "de"];

$pattern = implode("|", $excludeKeywords);
$result = preg_grep("/$pattern/i", $array);

// Positive (Reindex)
print_r(array_values($result));

// Negative (Reindex)
$result = array_diff($array, $result);
print_r(array_values($result));

Demo

了解更多:

管道(ab | de) = https://www.regular-expressions.info/alternation.html