如何重构这个不可读的 PHP for 循环?
How to refactor this unreadable PHP for-loops?
我很难理解遗留项目中的这行代码。此外 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]);
这几行实际上做了什么,我如何让它更具可读性?
for (a ; b ; c)
形式的 For 循环在 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()
这样的情况,这并不是什么大问题。但是如果你的条件是一个昂贵的函数调用,你会想把它从循环中拉出来。
第一部分是初始化;
第二部分是循环继续的测试条件;
第三部分是执行每次迭代的操作。因此,您可以在循环之前移动第一部分,在循环内移动第三部分。
;
终止循环,因此需要将其删除并替换为 { }
以包含循环体:
$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;
}
你可以从分解语法开始理解它。 For 循环有 3 个部分:一个 setter、一个条件和一个 getter。 setter 是您可以声明封装在 for 循环中的变量的地方。条件是必须满足什么参数才能继续循环。 getter 是您可以在循环时操作变量的地方,尽管它主要用于递增。 getter 或 setter 中可以使用逗号来指定多个命令。
for(<setter>;<condition>;<getter>)
for($var = 0, $var2 = 0; $var < 10; $var++, $var2 = 5 + $var)
getter 可以被滥用为单行代码,尽管这是一种糟糕的做法。以上可以翻译为:
for($var = 0, $var2 = 0; $var < 10; $var++) {
$var2 = 5 + $var;
}
我很难理解遗留项目中的这行代码。此外 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]);
这几行实际上做了什么,我如何让它更具可读性?
for (a ; b ; c)
形式的 For 循环在 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()
这样的情况,这并不是什么大问题。但是如果你的条件是一个昂贵的函数调用,你会想把它从循环中拉出来。
第一部分是初始化;
第二部分是循环继续的测试条件;
第三部分是执行每次迭代的操作。因此,您可以在循环之前移动第一部分,在循环内移动第三部分。
;
终止循环,因此需要将其删除并替换为 { }
以包含循环体:
$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;
}
你可以从分解语法开始理解它。 For 循环有 3 个部分:一个 setter、一个条件和一个 getter。 setter 是您可以声明封装在 for 循环中的变量的地方。条件是必须满足什么参数才能继续循环。 getter 是您可以在循环时操作变量的地方,尽管它主要用于递增。 getter 或 setter 中可以使用逗号来指定多个命令。
for(<setter>;<condition>;<getter>)
for($var = 0, $var2 = 0; $var < 10; $var++, $var2 = 5 + $var)
getter 可以被滥用为单行代码,尽管这是一种糟糕的做法。以上可以翻译为:
for($var = 0, $var2 = 0; $var < 10; $var++) {
$var2 = 5 + $var;
}