简体   繁体   English

PHP 检查字符串数组是否包含子字符串数组中的任何值

[英]PHP Check if an array of strings contains any value from an array of substrings

For eg.例如。 I have 2 arrays:我有 2 个 arrays:

$arr1 = array("cake", "make"); and $arr2 = array("birthday cake", "maker", "a random index");$arr2 = array("birthday cake", "maker", "a random index");

I want to check if both the values of $arr1 exist in $arr2 as a substring.我想检查$arr1的两个值是否作为 substring 存在于$arr2中。 $arr2 may also have other elements, but it doesn't matter if it contains all the indexes of $arr1 as substrings. $arr2也可能有其他元素,但它是否包含$arr1的所有索引作为子字符串并不重要。

I know the standard nested-loop approach to this but I don't want to use it as the performance will be terrible (as I have got a large array).我知道标准的嵌套循环方法,但我不想使用它,因为性能会很糟糕(因为我有一个大数组)。 I wanted to ask if PHP contains a built in function for this, or if there is an alternative method to accomplish this with a better time complexity [ preferrably O(log n), but O(n) will do as well ].我想问一下 PHP 是否包含内置的 function ,或者是否有另一种方法可以以更好的时间复杂度完成此任务[最好是 O(log n),但 O(n) 也可以]。

If as you say you have a large array to check, optimize the processing of the arrays.如果你说你有一个大数组要检查,优化 arrays 的处理。

  1. As soon as you fail to find one of the items in arr1, its all over terminate and return false一旦您在 arr1 中找不到其中一项,它就会全部终止并返回 false
  2. Pass the array parameters by reference, so no copying the arrays to the stack通过引用传递数组参数,因此无需将 arrays 复制到堆栈
  3. Put the most likely thing NOT to be found in arr2 at the beginning of arr1将最有可能在 arr2 中找不到的东西放在 arr1 的开头
$arr1 = array( "cake", "make");
$arr2 = array("birthday cake", "maker", "a random index");

// pass arrays by reference, so you dont have to create copies 
// of large arrays on to the stack
function testThem(&$arr1, &$arr2) {
    // as soon as a unfound situation is indicated, return from the function with false
    foreach ($arr1 as $a1) {
        $found = false;
        foreach ($arr2 as $a2) {
            if (strpos($a2, $a1) !== false) {
                //as soon as a found occurs break out of this foreach
                $found = true;
                break;
            }
        }
        // If we get here with a $found still = false
        // we didnt find one of the things in $arr1 within $arr2 
        // so no more looping required. Finish and return false
        if (!$found) { 
            return false;
        }
    }    
    // only if we find all the items do we eventually get here after lots of loops
    return true;
}


if ( testThem($arr1, $arr2) ) {
    echo 'All Found';
} else {
    echo 'Something not found';
}

If we make the string of the second array如果我们制作第二个数组的字符串

$arr2 = implode('###',$arr2);

and then use array_filter as below:然后使用 array_filter 如下:

$result = array_filter($arr1,function($value) use($arr2){
    return (strpos($value,$arr2)!==false)?$value:false;
});

print_r(array_filter($result));

Here we have all the matching sub-strings from $arr1.这里我们有来自 $arr1 的所有匹配子字符串。

I think nested loops are the only way, but to make it more efficient break out of the loops as soon as the answer is determined.我认为嵌套循环是唯一的方法,但是一旦确定答案,就可以更有效地跳出循环。

$found_all = true;
foreach ($arr1 as $str1) {
    $found1 = false;
    foreach ($arr2 as $str2) {
        if (strpos($str2, $str1) !== false) {
            $found1 = true;
            break;
        }
    }
    if (!$found1) {
        $found_all = false;
        break;
    }
}
echo $found_all ? "All found" : "Not all found";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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