«Перерыв продолжается» существуют в PHP?

Для контекста по этому вопросу, пожалуйста, см. Мой недавний пост. В приведенной ниже функции 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 Под «разрывом продолжения» я подразумеваю разорвать внутренний цикл, затем продолжить внешний

1

Решение

есть продолжение (пропустить)

<?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;
}
}
3

Другие решения

К сожалению, в 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;
}
1