问题很简单。我有一个foreach循环在我的代码:

foreach($array as $element) {
    //code
}

在这个循环中,当我们在第一次或最后一次迭代时,我希望做出不同的反应。

如何做到这一点?


当前回答

对于SQL查询生成脚本,或任何对第一个或最后一个元素执行不同操作的脚本,避免使用不必要的变量检查要快得多(几乎快两倍)。

目前公认的解决方案使用循环和循环内的检查,将使every_single_iteration,正确的(快速)方法如下:

$numItems = count($arr);
$i=0;
$firstitem=$arr[0];
$i++;
while($i<$numItems-1){
    $some_item=$arr[$i];
    $i++;
}
$last_item=$arr[$i];
$i++;

一个自制的基准测试显示如下:

Test1: 100000次模型morg

时间:1869.3430423737毫秒

Test2:模型运行100000次

时间:3235.6359958649毫秒

因此,很明显,支票的成本很高,当然,你添加的变量越多,情况就越糟糕;)

其他回答

上面的一个更简化的版本,并假设您不使用自定义索引……

$len = count($array);
foreach ($array as $index => $item) {
    if ($index == 0) {
        // first
    } else if ($index == $len - 1) {
        // last
    }
}

版本2 -因为我已经讨厌使用else除非必要。

$len = count($array);
foreach ($array as $index => $item) {
    if ($index == 0) {
        // first
        // do something
        continue;
    }

    if ($index == $len - 1) {
        // last
        // do something
        continue;
    }
}

这很简单!

// Set the array pointer to the last key
end($array);
// Store the last key
$lastkey = key($array);  
foreach($array as $key => $element) {
    ....do array stuff
    if ($lastkey === key($array))
        echo 'THE LAST ELEMENT! '.$array[$lastkey];
}

谢谢你@billynoah整理了最后的问题。

如果您更喜欢不需要在循环外初始化计数器的解决方案,那么您可以将当前迭代键与告诉您数组的最后/第一个键的函数进行比较。

PHP 7.3及更新版本:

foreach ($array as $key => $element) {
    if ($key === array_key_first($array)) {
        echo 'FIRST ELEMENT!';
    }

    if ($key === array_key_last($array)) {
        echo 'LAST ELEMENT!';
    }
}

PHP 7.2及以上版本:

PHP 7.2已经是EOL(生命终结),所以这里只是作为历史参考。避免使用。

foreach ($array as $key => $element) {
    reset($array);
    if ($key === key($array)) {
        echo 'FIRST ELEMENT!';
    }

    end($array);
    if ($key === key($array)) {
        echo 'LAST ELEMENT!';
    }
}

对于键和值,这也是有效的:

foreach ($array as $key => $value) {
    if ($value === end($array)) {
        echo "LAST ELEMENT!";
    }
}

为了找到最后一项,我发现这段代码每次都有效:

foreach( $items as $item ) {
    if( !next( $items ) ) {
        echo 'Last Item';
    }
}