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

前端 未结 20 1116
遇见更好的自我
遇见更好的自我 2020-11-22 16:45

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

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

In this loop, I want to r

相关标签:
20条回答
  • 2020-11-22 17:18

    1: Why not use a simple for statement? Assuming you're using a real array and not an Iterator you 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...

    $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 Sets to store your tree structure. Additionally you can improve the whole thing by using recursive functions.

    0 讨论(0)
  • 2020-11-22 17:18

    Using a Boolean variable is still the most reliable, even if you want to check the first appearance of a $value (I found it more useful in my situation and in many situations), such like this:

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

    Then how about !next( $array ) to find the last $value which will return true if there's no next() value to iterate.

    And I prefer to use a for loop instead of foreach if I were going to use a counter, like this:

    $len = count( $array );
    for ( $i = 0; $i < $len; $i++ ) {
        $value = $array[$i];
        if ($i === 0) {
            // first
        } elseif ( $i === $len - 1 ) {
            // last
        }
        // …
        $i++;
    }
    
    0 讨论(0)
  • 2020-11-22 17:19

    For SQL query generating scripts, or anything that does a different action for the first or last elements, it is much faster (almost twice as fast) to avoid using unneccessary variable checks.

    The current accepted solution uses a loop and a check within the loop that will be made every_single_iteration, the correct (fast) way to do this is the following :

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

    A little homemade benchmark showed the following:

    test1: 100000 runs of model morg

    time: 1869.3430423737 milliseconds

    test2: 100000 runs of model if last

    time: 3235.6359958649 milliseconds

    And it's thus quite clear that the check costs a lot, and of course it gets even worse the more variable checks you add ;)

    0 讨论(0)
  • 2020-11-22 17:20

    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.

    $len = count($array);
    foreach ($array as $index => $item) {
        if ($index == 0) {
            // first
            // do something
            continue;
        }
    
        if ($index == $len - 1) {
            // last
            // do something
            continue;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 17:22
    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();
       }
    }
    
    0 讨论(0)
  • 2020-11-22 17:23

    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.

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

    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
    }
    ?>
    
    0 讨论(0)
提交回复
热议问题