Для контекста по этому вопросу, пожалуйста, см. Мой недавний пост. В приведенной ниже функции break continue
позволил бы мне опустить последний if
состояние. (см. комментарий во внутреннем цикле for)
function strposHypothetical($haystack, $needle) {
$haystackLength = strlen($haystack);
$needleLength = strlen($needle);//for this question let's assume > 0
$pos = false;
for($i = 0; $i < $haystackLength; $i++) {
for($j = 0; $j < $needleLength; $j++) {
$thisSum = $i + $j;
if (($thisSum > $haystackLength) ||
($needle[$j] !== $haystack[$thisSum]))
break;
// if I could "break continue" I could omit the
// if ($j === $needleLength)
// below and just write $pos = $i; break;
}
if ($j === $needleLength) {
$pos = $i;
break;
}
}
return $pos;
}
Я видел несколько похожих постов, таких как этот тот, который не совсем отвечает на мой вопрос. Я не хочу рефакторинг функции выше. Мне не нужно break 2
ни continue 2
, Заметка break 2
не будет работать во внутреннем цикле, потому что будут пропущены необходимые итерации во внешнем цикле for. continue 2
также не удается, потому что внутренний цикл for должен повторяться до конца стрелки. Является break continue
возможно в PHP?
Заметка Я попробовал это и получил фатальную ошибку, поэтому я предполагаю, что либо ответ «Нет», либо я его неправильно реализовал.
Заметка 2 Под «разрывом продолжения» я подразумеваю разорвать внутренний цикл, затем продолжить внешний
есть продолжение (пропустить)
<?php while (list($key, $value) = each($arr)) { if (!($key % 2)) { // skip even members continue; } do_something_odd($value); } ?>
http://php.net/manual/en/control-structures.continue.php
for($i = 0; $i < $haystackLength; $i++) {
for($j = 0; $j < $needleLength; $j++) {
$thisSum = $i + $j;
if (($thisSum > $haystackLength) ||
($needle[$j] !== $haystack[$thisSum]))
continue;
}
if ($j === $needleLength) {
$pos = $i;
break;
}
}
К сожалению, в PHP нет такой конструкции, как «break continue», однако, перемещая всю логику во внутренний цикл, вы можете избежать флагов и необходимости полностью «break continue». Думаю, это не совсем упрощает логику, так что, YMMV.
function strposHypothetical( $haystack, $needle ){
$haystackLength = strlen( $haystack );
$needleLength = strlen( $needle );
$pos = false;
for( $i = 0; $i < $haystackLength; $i++ ){
for( $j = 0; $j < $needleLength; $j++ ){
$thisSum = $i + $j;
if( ( $thisSum > $haystackLength )
|| ( $needle[ $j ] !== $haystack[ $thisSum ] ) )
break;
else if( $j === $needleLength ){
$pos = $i;
break 2;
}
}
}
return $pos;
}
Чтобы повысить производительность, вы можете даже изменить ее, добавив немного производительности, не сохраняя результат переменной $ i + $ j в переменной, но избавляясь от этой дополнительной переменной и делая флаг $ pos-подобным:
function strposHypothetical( $haystack, $needle ){
$haystackLength = strlen( $haystack );
$needleLength = strlen( $needle );
$pos = false;
for($i = 0; $i < $haystackLength; $i++) {
$pos = $i;
for($j = 0; $j < $needleLength; $j++) {
if(
( $pos + $j > $haystackLength )
|| ( $needle[ $j ] !== $haystack[ $pos + $j ] )
){
$pos = false;
break;
}
}
if( $pos !== false )
break;
}
return $pos;
}
Вчера вечером у меня было время подумать, и этот рефакторинг должен получить максимальную производительность, заставляя сравнения и назначать, что цикл for уже выполняет большую часть работы. Это также немного сокращает код;
function strposHypothetical( $haystack, $needle ){
$haystackLength = strlen( $haystack );
$needleLength = strlen( $needle );
for( $i = $haystackLength, $pos = false; $i >= 1 && $pos === false; $i-- ){
for( $j = $needleLength - 1, $pos = $i - 1; $j >= 0 && $pos !== false; $j-- ){
$pos--;
if( $pos < 0 || $needle[ $j ] !== $haystack[ $pos ] )
$pos = false;
}
}
return $pos;
}