Php 如何有效地检查(strpos(…)阵列的所有元素?

Php 如何有效地检查(strpos(…)阵列的所有元素?,php,arrays,performance,Php,Arrays,Performance,我想检查数组的所有元素,并确定其中是否至少有一个元素以给定字符串作为前缀: public function validateStringByPrefix(string $string, $prefix) { $valid = false; if (is_string($prefix)) { if (strpos($string, $prefix) === 0) { $valid = true; } } elseif

我想检查数组的所有元素,并确定其中是否至少有一个元素以给定字符串作为前缀:

public function validateStringByPrefix(string $string, $prefix)
{
    $valid = false;
    if (is_string($prefix)) {
        if (strpos($string, $prefix) === 0) {
            $valid = true;
        }
    } elseif (is_array($prefix)) {
        foreach ($prefix as $partPrefix) {
            if (strpos($string, $partPrefix) === 0) {
                $valid = true;
                break;
            }
        }
    }
    return $valid;
}
是否可能/如何以更有效的方式实现同样的目标?


(这是一种便宜的方法,但在我的应用程序中调用了很多次,因此即使是最小的改进也可能显著提高应用程序的性能。)

您可以尝试下一种解决方案:

public function validateStringByPrefix(string $string, $prefix)
{
    return (bool)array_filter((array)$prefix, function($prefix) use ($string) {
        return strpos($string, $prefix)===0;
    });
}
另外,如果您没有几个大数组(带前缀),我的解决方案效率较低,您可以将我们的方法结合起来,如下所示:

public function validateStringByPrefix(string $string, $prefix)
{
    if($string=='') {
        return false;
    }
    foreach ((array)$prefix AS $subprefix) {
        if (strpos($string, $subprefix)===0) {
            return true;
        }
    }
    return false;
}

您可以尝试下一个解决方案:

public function validateStringByPrefix(string $string, $prefix)
{
    return (bool)array_filter((array)$prefix, function($prefix) use ($string) {
        return strpos($string, $prefix)===0;
    });
}
另外,如果您没有几个大数组(带前缀),我的解决方案效率较低,您可以将我们的方法结合起来,如下所示:

public function validateStringByPrefix(string $string, $prefix)
{
    if($string=='') {
        return false;
    }
    foreach ((array)$prefix AS $subprefix) {
        if (strpos($string, $subprefix)===0) {
            return true;
        }
    }
    return false;
}

去罗马有很多方法

//your array to test for
$array=[];
//set valid to false
$valid=false;
//setup prefixes array or not
$prefix='whatever';
//make array if you dont have one
!is_array($prefix) AND $prefix=array($prefix);
//prepare for use as REGEX
$prefix=implode('|',$prefix);
//do the work
array_walk($array,function($val,$key) use(&$valid,$prefix){
       if (!$valid && preg_match("#^($prefix)#",$key)) {
            $valid = true;
       }
});
var_export($valid);
我在这里使用了
preg_match
,因为
$prefix
可以是一个数组,所以数学应该是:
n+strpos()调用
vs.
一个preg_match()调用


在单个项目匹配之后,不再调用
preg\u match
,只需迭代到最后再执行。

有很多方法可以

//your array to test for
$array=[];
//set valid to false
$valid=false;
//setup prefixes array or not
$prefix='whatever';
//make array if you dont have one
!is_array($prefix) AND $prefix=array($prefix);
//prepare for use as REGEX
$prefix=implode('|',$prefix);
//do the work
array_walk($array,function($val,$key) use(&$valid,$prefix){
       if (!$valid && preg_match("#^($prefix)#",$key)) {
            $valid = true;
       }
});
var_export($valid);
我在这里使用了
preg_match
,因为
$prefix
可以是一个数组,所以数学应该是:
n+strpos()调用
vs.
一个preg_match()调用



在单个项目匹配后,不再调用
preg\u match
,只需迭代到最后和结束。

如果您提供一些示例数据,这会很有帮助,这不是一个很大的改进,而是将$valid设置为true并打破循环,您可以在那里返回true,而不是返回$valid set return false如果它真的位于字符串的开头,那么只需使用
substr($str,0,$len)==$prefix
?如果字符串比前缀长,应该更快一些吗?像往常一样-将其基准化以确认我希望您已经研究过使用它,如果您提供一些示例数据(这不是一个很大的改进,而是将$valid设置为true并打破循环),那么它会有所帮助,您可以在那里返回true,而不是返回$valid set return false如果它真的位于字符串的开头,那么只需使用
substr($str,0,$len)==$prefix
?如果字符串比前缀长,应该更快一些吗?像往常一样-对其进行基准测试以确认我希望您已经研究过使用我不太确定这是否更有效:在这里,您将评估OP的解决方案在找到匹配项后返回的所有值。我不确定这是否更有效:在这里,您将评估OP的解决方案在找到匹配项后返回的所有值。我不知道正则表达式将比strpos更高效,我认为遍历整个阵列不是一个好的解决方案。至少当OP发现它是有效的时,它最初的想法很早就回来了。他们并不是要验证每个项目是否有效,只是验证数组中的单个项目是否有效。@haliphax,正如我所说的
有很多方法可以实现
,例如,在10000次迭代中运行测试,其中创建了3个类和2个闭包,并且在每次迭代中运行strpos/inbode/explode/preg_match函数。脚本需要1秒钟。在这种情况下,没有比这更有效的方法了,因为工作并不那么繁重。在我的示例中,我检查
$有效
跳过不再需要的预匹配调用。无论如何,我只是把代码放在这里,给你一些提示和指导。@haliphax最后:如果
$prefix
是一个有10个前缀的数组,那么数学是:
10个strpos vs 1个preg_match
你说什么?我说:你的数学有问题。第一个前缀将结束循环,因此它是1
strpos
vs.1
preg\u match
,它包含在对
array\u walk
匿名函数的9个额外的、不必要的调用中。@haliphax
foreach($partPrefix的前缀){
你错过了最初的OP帖子中的部分了吗?
9额外的、不必要的调用也可以忽略。但最后,有很多方法可以到达罗马,php并不是公路上最好的驱动程序,所以让我们按我们想要的方式驾驶吧;)祝你玩得愉快我不知道正则表达式会比
strpos
更高效,我不相信ve遍历整个数组是一个很好的解决方案。至少OP的初始想法在发现它有效时很早就返回了。他们并没有试图验证每个项目都有效,只是验证数组中的单个项目有效。@haliphax正如我所说的
有很多方法可以解决问题
,例如,我们运行了10000次迭代的测试,其中3次迭代SSE和2 closure在每次迭代中创建并运行strpos/infrade/explode/preg_match函数。脚本需要1秒。在这里,没有更有效的方法,因为工作不是那么繁重。在我的示例中,我检查
!$valid
以跳过不再需要的preg_match调用。然而,我刚刚放弃了他在这里编码是为了给出提示和指示。@haliphax,最后:如果
$prefix
是一个有10个前缀的数组,那么数学是:
10个strpos vs 1个preg_match
你说什么?我说:你的数学有问题。第一个前缀将结束循环,所以它是1
strpos
vs.1
preg_match
,它被包装在9个额外的指针中ss调用
array\u walk
匿名函数。@haliphax
foreach($partPrefix作为$partPrefix的前缀){
您是否错过了原始OP帖子中的部分?
9其他不必要的调用也可以忽略。但最后,有很多方法可以到达罗马,php并不是公路上最好的驱动程序,所以让我们随心所欲地驾驶吧;)祝您玩得愉快