php 如何确定foreach循环中的第一次和最后一次迭代?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1070244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 00:51:51  来源:igfitidea点击:

How to determine the first and last iteration in a foreach loop?

phploopsforeach

提问by mehdi

The question is simple. I have a foreachloop in my code:

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

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

In this loop, I want to react differently when we are in first or last iteration.

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

How to do this?

这该怎么做?

采纳答案by Gumbo

You could use a counter:

您可以使用计数器:

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

回答by Rok Kralj

If you prefer a solution that does not require the initialization of the counter outside the loop, I propose comparing the current iteration key against the function that tells you the last / first key of the array.

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

This becomes somewhat more efficient (and more readable) with the upcoming PHP 7.3.

在即将推出的 PHP 7.3 中,这会变得更高效(也更易读)。

Solution for PHP 7.3 and up:

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

Solution for all PHP versions:

所有 PHP 版本的解决方案:

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

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

回答by Yojance

To find the last item, I find this piece of code works every time:

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

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

回答by Hayden

A more simplified version of the above and presuming you're not using custom indexes...

上面更简化的版本,并假设您没有使用自定义索引...

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

Version 2 - Because I have come to loathe using the else unless necessary.

版本 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;
    }
}

回答by Carlos Lima

You could remove the first and last elements off the array and process them separately.

您可以从数组中删除第一个和最后一个元素并分别处理它们。

Like this:

像这样:

<?php
$array = something();
$first = array_shift($array);
$last = array_pop($array);

// do something with $first
foreach ($array as $item) {
 // do something with $item
}
// do something with $last
?>

Removing all the formatting to CSS instead of inline tags would improve your code and speed up load time.

将所有格式删除为 CSS 而不是内联标签将改进您的代码并加快加载时间。

You could also avoid mixing HTML with php logic whenever possible.

您还可以尽可能避免将 HTML 与 php 逻辑混合。

Your page could be made a lot more readable and maintainable by separating things like this:

通过将以下内容分开,可以使您的页面更具可读性和可维护性:

<?php
function create_menu($params) {
  //retrieve menu items 
  //get collection 
  $collection = get('xxcollection') ;
  foreach($collection as $c) show_collection($c);
}

function show_subcat($val) {
  ?>
    <div class="sub_node" style="display:none">
      <img src="../images/dtree/join.gif" align="absmiddle" style="padding-left:2px;" />
      <a id="'.$val['xsubcatid'].'" href="javascript:void(0)" onclick="getProduct(this , event)" class="sub_node_links"  >
        <?php echo $val['xsubcatname']; ?>
      </a>
    </div>
  <?php
}

function show_cat($item) {
  ?>
    <div class="node" >
      <img src="../images/dtree/plus.gif" align="absmiddle" class="node_item" id="plus" />
      <img src="../images/dtree/folder.gif" align="absmiddle" id="folder">
      <?php echo $item['xcatname']; ?>
      <?php 
        $subcat = get_where('xxsubcategory' , array('xcatid'=>$item['xcatid'])) ;
        foreach($subcat as $val) show_subcat($val);
      ?>
    </div>
  <?php
}

function show_collection($c) {
  ?>
    <div class="parent" style="direction:rtl">
      <img src="../images/dtree/minus.gif" align="absmiddle" class="parent_item" id="minus" />
      <img src="../images/dtree/base.gif" align="absmiddle" id="base">
      <?php echo $c['xcollectionname']; ?>
      <?php
        //get categories 
        $cat = get_where('xxcategory' , array('xcollectionid'=>$c['xcollectionid']));
        foreach($cat as $item) show_cat($item);
      ?>
    </div>
  <?php
}
?>

回答by Sydwell

Simply this works!

简直就是这样!

// 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];
}

Thank you @billynoah for your sorting out the endissue.

感谢@billynoah 解决了最终问题。

回答by sstauross

An attempt to find the first would be:

尝试找到第一个将是:

$first = true; 
foreach ( $obj as $value )
{
  if ( $first )
  {
    // do something
    $first = false; //in order not to get into the if statement for the next loops
  }
  else
  {
    // do something else for all loops except the first
  }
}

回答by okoman

1: Why not use a simple forstatement? Assuming you're using a real array and not an Iteratoryou could easily check whether the counter variable is 0 or one less than the whole number of elements. In my opinion this is the most clean and understandable solution...

1:为什么不使用简单的for语句?假设您使用的是真实数组而不是数组,Iterator您可以轻松检查计数器变量是 0 还是比元素总数少 1。在我看来,这是最干净和易于理解的解决方案......

$array = array( ... );

$count = count( $array );

for ( $i = 0; $i < $count; $i++ )
{

    $current = $array[ $i ];

    if ( $i == 0 )
    {

        // process first element

    }

    if ( $i == $count - 1 )
    {

        // process last element

    }

}

2: You should consider using Nested Setsto store your tree structure. Additionally you can improve the whole thing by using recursive functions.

2:您应该考虑使用嵌套集来存储您的树结构。此外,您可以通过使用递归函数来改进整个事情。

回答by Ivan

Best answer:

最佳答案:

$arr = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

foreach ($arr as $a) {

// This is the line that does the checking
if (!each($arr)) echo "End!\n";

echo $a."\n";

}

回答by TheMadDeveloper

The most efficient answerfrom @morg, unlike foreach, only works for proper arrays, not hash map objects. This answer avoids the overhead of a conditional statement for every iteration of the loop, as in most of these answers (including the accepted answer) by specificallyhandling the first and last element, and looping over the middle elements.

来自@morg的最有效的答案与 不同foreach,它仅适用于正确的数组,而不适用于哈希映射对象。该答案通过专门处理第一个和最后一个元素并循环遍历中间元素,避免了循环每次迭代的条件语句的开销,就像在大多数这些答案(包括接受的答案)中一样。

The array_keysfunction can be used to make the efficient answer work like 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++;

I haven't done benchmarking on this, but no logic has been added to the loop, which is were the biggest hit to performance happens, so I'd suspect that the benchmarks provided with the efficient answer are pretty close.

我还没有对此进行基准测试,但没有在循环中添加任何逻辑,这是对性能的最大影响,所以我怀疑提供有效答案的基准非常接近。

If you wanted to functionalizethis kind of thing, I've taken a swing at such an iterateList function here. Although, you might want to benchmark the gist code if you're super concerned about efficiency. I'm not sure how much overhead all the function invocation introduces.

如果您想对这种事情进行功能化,我在这里尝试了这样一个iterateList 函数。虽然,如果您非常关心效率,您可能想要对 gist 代码进行基准测试。我不确定所有函数调用会带来多少开销。