问题很简单。我有一个foreach循环在我的代码:
foreach($array as $element) {
//code
}
在这个循环中,当我们在第一次或最后一次迭代时,我希望做出不同的反应。
如何做到这一点?
问题很简单。我有一个foreach循环在我的代码:
foreach($array as $element) {
//code
}
在这个循环中,当我们在第一次或最后一次迭代时,我希望做出不同的反应。
如何做到这一点?
当前回答
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();
}
}
其他回答
当我遇到同样的问题时,我遇到了这条线索。我只需要得到第一个元素,然后我重新分析我的代码,直到这出现在我的脑海中。
$firstElement = true;
foreach ($reportData->result() as $row)
{
if($firstElement) { echo "first element"; $firstElement=false; }
// Other lines of codes here
}
上面的代码是伟大的和完整的,但如果你只需要第一个元素,那么你可以试试这段代码。
来自@morg的最有效的答案,与foreach不同,它只适用于适当的数组,而不是哈希映射对象。这个答案避免了每次循环迭代都使用条件语句的开销,就像大多数这些答案(包括接受的答案)一样,通过专门处理第一个和最后一个元素,并遍历中间的元素。
array_keys函数可以像foreach一样高效地执行:
$keys = array_keys($arr);
$numItems = count($keys);
$i=0;
$firstItem=$arr[$keys[0]];
# Special handling of the first item goes here
$i++;
while($i<$numItems-1){
$item=$arr[$keys[$i]];
# Handling of regular items
$i++;
}
$lastItem=$arr[$keys[$i]];
# Special handling of the last item goes here
$i++;
我还没有对此进行基准测试,但没有向循环添加逻辑,这是对性能影响最大的地方,因此我怀疑提供有效答案的基准测试非常接近。
如果您想对这类东西进行函数化,我已经在这里尝试了这样一个iterateList函数。不过,如果您非常关心效率,您可能需要对主旨代码进行基准测试。我不确定所有函数调用引入了多少开销。
对于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毫秒
因此,很明显,支票的成本很高,当然,你添加的变量越多,情况就越糟糕;)
你也可以使用匿名函数:
$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旁边,如果需要,同样通过引用。
不确定是否还有必要。但是下面的解决方案应该与迭代器一起工作,并且不需要计数。
<?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;
}
}
}