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

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

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

如何做到这一点?


当前回答

你也可以使用匿名函数:

$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)传递它。 在匿名函数内部需要的任何外部变量,都必须在use构造中将它们列在$indexOfLastElement旁边,如果需要,同样通过引用。

其他回答

使用布尔变量仍然是最可靠的,即使你想检查$值的第一次出现(我发现它在我的情况和许多情况下更有用),比如:

$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)查找最后一个$值,如果没有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( $items as $item ) {
    if( !next( $items ) ) {
        echo 'Last Item';
    }
}

使用reset($array)和end($array)

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

    }

演示repl.it

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

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!';
    }
}

不确定是否还有必要。但是下面的解决方案应该与迭代器一起工作,并且不需要计数。

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