这个问题很简单。我在我的代码中有一个foreach
循环:
foreach($array as $element) {
//code
}
在这个循环中,我想在第一次或最后一次迭代时有不同的反应。如何实现?对于生成SQL查询脚本或任何针对第一个或最后一个元素执行不同操作的内容,避免使用不必要的变量检查可以提高速度(几乎快两倍)。
目前被接受的解决方案使用了循环和循环内的检查,每次迭代都会进行一次检查,正确(快速)的做法是:
$numItems = count($arr);
$i=0;
$firstitem=$arr[0];
$i++;
while($i<$numItems-1){
$some_item=$arr[$i];
$i++;
}
$last_item=$arr[$i];
$i++;
一个小巧的自制基准测试显示如下:
测试1:运行模型morg 100000次
时间:1869.3430423737毫秒
测试2:运行模型if last 100000次
时间:3235.6359958649毫秒
很明显,这个检查代价非常高,当然,你添加的变量检查越多,情况就会变得更糟糕 ;)
将输出:
0: , 1: One, 2: ,` - Seika85{'one':"1 1 1",0:"",1:"One",2:"",3:"",4:"Four"}
,但空元素在计数时被忽略,你正在计算已定义的“things”的数量!赏金即将到来!这个答案值得获得赏金,但如果@Morg.离开了,那就没有意义了。我会把赏金给一个可能不会再使用SO的人!如果他回来并改进了他的答案,他应该得到赏金! - mjz19910array_keys
函数获取哈希映射的属性,这个属性您可以像数组一样进行操作。请参见我的“改进”答案。 - TheMadDeveloper$querySet = "";
foreach ($fieldSet as $key=>$value) {
$value = $db->dbLink->quote($value);
$querySet .= "$key = $value, ";
}
$querySet = substr_replace($querySet, "", -2);
$queryString = "UPDATE users SET $querySet WHERE user_ID = '$user_ID'";
- Rovshan Mamedov即使你想要检查一个$value
的第一次出现,使用布尔变量仍然是最可靠的方法 (在我的情况和许多情况下,我发现这更有用),像这样:
$is_first = true;
foreach( $array as $value ) {
switch ( $value ) {
case 'match':
echo 'appeared';
if ( $is_first ) {
echo 'first appearance';
$is_first = false;
}
break;
}
}
if( !next( $array ) ) {
echo 'last value';
}
}
!next( $array )
查找最后一个$value
,如果没有要迭代的next()
值,则返回true
。for
循环而不是foreach
,像这样:$len = count( $array );
for ( $i = 0; $i < $len; $i++ ) {
$value = $array[$i];
if ($i === 0) {
// first
} elseif ( $i === $len - 1 ) {
// last
}
// …
$i++;
}
对于键和值,这同样有效:
foreach ($array as $key => $value) {
if ($value === end($array)) {
echo "LAST ELEMENT!";
}
}
<?php
$arrays = [1,2,3,4,5];
$first = reset($arrays);
$last = end($arrays);
foreach( $arrays as $array )
{
if ( $first == $array )
{
echo "<li>{$array} first</li>";
}
else if ( $last == $array )
{
echo "<li>{$array} last</li>";
}
else
{
echo "<li>{$array}</li>";
}
}
我看到了这个帖子,因为我也遇到了同样的问题。我只需要获取第一个元素,然后重新分析我的代码,直到我想到这个方法。
$firstElement = true;
foreach ($reportData->result() as $row)
{
if($firstElement) { echo "first element"; $firstElement=false; }
// Other lines of codes here
}
不确定是否仍然需要。但是以下解决方案应该适用于迭代器,并且不需要 count
。
<?php
foreach_first_last(array(), function ($key, $value, $step, $first, $last) {
echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
foreach_first_last(array('aa'), function ($key, $value, $step, $first, $last) {
echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
echo PHP_EOL;
foreach_first_last(array('aa', 'bb', 'cc'), function ($key, $value, $step, $first, $last) {
echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
echo PHP_EOL;
function foreach_first_last($array, $cb)
{
$next = false;
$current = false;
reset($array);
for ($step = 0; true; ++$step) {
$current = $next;
$next = each($array);
$last = ($next === false || $next === null);
if ($step > 0) {
$first = $step == 1;
list ($key, $value) = $current;
if (call_user_func($cb, $key, $value, $step, $first, $last) === false) {
break;
}
}
if ($last) {
break;
}
}
}
$indexOfLastElement = count($array) - 1;
array_walk($array, function($element, $index) use ($indexOfLastElement) {
// do something
if (0 === $index) {
// first element‘s treatment
}
if ($indexOfLastElement === $index) {
// last not least
}
});
还有三点需要提到:
array_values
对数组进行处理。$element
,你必须通过引用传递它(&$element
)。$indexOfLastElement
列在 use
结构的旁边,如果需要,也要通过引用传递。最简单的方法是:
$array = [9,5,6,4,7,8];
$current_iteration = 0;
foreach($array as $item){
if( 0 === $current_iteration ){
echo 'this is the first item: ' . $item;
}
if( (count($array) - 1) === $current_iteration){
echo 'this is the last item: ' . $item;
}
$current_iteration++;
}
您可以使用计数器和数组长度。
$array = array(1,2,3,4);
$i = 0; $len = count($array); foreach ($array as $item) { if ($i === 0) { // 第一个 } else if ($i === $len - 1) { // 最后一个 } // … $i++; }
foreach ($arquivos as $key => $item) {
reset($arquivos);
// FIRST AHEAD
if ($key === key($arquivos) || $key !== end(array_keys($arquivos)))
$pdf->cat(null, null, $key);
// LAST
if ($key === end(array_keys($arquivos))) {
$pdf->cat(null, null, $key)
->execute();
}
}