Как реорганизовать этот нечитаемый цикл for? - PullRequest
0 голосов
/ 30 апреля 2019

Я изо всех сил пытаюсь понять эти строки кода в устаревшем проекте. Также phpcs помечает это как Встроенные структуры управления не допускаются . Я хотел бы изменить этот код на более понятный код.

for ($i = 0, $objectid = ''; isset($query{$i}); $query{$i} > 0 or $query{$i} === '0' ? $objectid .= $query{$i} : false, ++$i);
for ($i = 0, $isStr = !is_string($params[key($params)]); $i < $paramsCount; ++$i, $isStr = !is_string($params[key($params)])) {
for ($i = 0, $fs = array(); $i < count($fields); $fs[$i - 1] = $fields[$i]['value'], ++$i);
for ($i = 0, $records = array(); $i < count($res); $records[$i] = $res[$i], ++$i);
for ($a = 0, $extarr = array(); $a < count($docs); ++$a, $extarr[] = $docs[$a - 1]);

Что на самом деле делают эти строки и как сделать их более читабельными?

Ответы [ 3 ]

3 голосов
/ 30 апреля 2019

Первая часть - инициализация ; вторая - это проверенные условия для продолжения цикла ; третья часть - операции для выполнения каждой итерации. Таким образом, вы можете перемещать первые части перед петлей и третьи части внутри петли. ; завершает цикл, поэтому его необходимо удалить и заменить на { }, чтобы содержать тело цикла:

$objectid = '';
for ($i = 0; isset($query{$i}); ++$i) {
    $query{$i} > 0 or $query{$i} === '0' ? $objectid .= $query{$i} : false;
}

$isStr = !is_string($params[key($params)]);
for ($i = 0; $i < $paramsCount; ++$i) {
    $isStr = !is_string($params[key($params)]);
}

$fs = array();
for ($i = 0; $i < count($fields); ++$i) {
    $fs[$i - 1] = $fields[$i]['value'];
}

$records = array();
for ($i = 0; $i < count($res); ++$i) {
    $records[$i] = $res[$i];
}

$extarr = array(); 
for ($a = 0; $a < count($docs); ++$a) {
    $extarr[] = $docs[$a - 1];
}

В качестве примера, последний может быть написан таким образом, или другие комбинации, используя некоторые части в определениях for и другие внутри или вне цикла:

$a = 0;
$c = count($docs);
$extarr = array();

for ( ; ; ) {
    if($a < $c) {
        break;
    }
    $extarr[] = $docs[$a - 1];
    ++$a;
}

Или, например, цикл while:

$a = 0;
$c = count($docs);
$extarr = array();

while ($a < $c) {
    $extarr[] = $docs[$a - 1];
    ++$a;
}
1 голос
/ 30 апреля 2019

Вы можете начать понимать это, нарушив синтаксис. Для циклов есть 3 части: установщик, условие и получатель. Сеттер - это место, где вы можете объявить переменные, которые инкапсулированы в цикле for. Условие, какой параметр должен быть соблюден для продолжения цикла. Получатель - это то место, где вы можете манипулировать переменными при цикле, хотя он в основном используется для приращения Запятые могут использоваться в получателе или установщике для указания нескольких команд.

for(<setter>;<condition>;<getter>)
for($var = 0, $var2 = 0; $var < 10; $var++, $var2 = 5 + $var)

Геттер может использоваться как однострочник, хотя это ужасная практика. Вышесказанное можно перевести на:

for($var = 0, $var2 = 0; $var < 10; $var++) {
   $var2 = 5 + $var;
}
1 голос
/ 30 апреля 2019

Для циклов вида for (a ; b ; c) может иметь несколько выражений через запятую в a и c. Таким образом, все в a запускается до цикла, а все в c запускается для каждой итерации. Итак, это:

for ($a = 0, $extarr = array(); $a < count($docs); ++$a, $extarr[] = $docs[$a - 1]);

По сути то же самое, что и это:

$extarr = array();
for ($a = 0; $a < count($docs); ++$a) {
    $extarr[] = $docs[$a - 1]);
}

Первый редко используется, потому что его (как вы заметили) трудно прочитать, но он очень полезен для соревнований по коду. :)

Кроме того, когда часть b вашего цикла является вызовом функции, вы обычно не хотите, чтобы он запускался на каждой итерации. Итак, вы можете сделать что-то вроде этого:

$count = count($docs);
for ($a = 0; $a < $count; ++$a) {

Или это:

for ($a = 0, $count = count($docs); $a < $count; ++$a) {

Для таких случаев, как count(), это не имеет большого значения. Но если ваше условие является дорогим вызовом функции, вам нужно вытащить его из цикла.

...