543 votes

Comment déterminer la première et la dernière itération dans une boucle foreach ?

La question est simple. J'ai un foreach dans mon code :

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

Dans cette boucle, je veux réagir différemment lorsque nous sommes dans la première ou la dernière itération.

Comment faire ?

0 votes

Vous devriez mettre à jour la question avec PHP. Javascript a aussi une boucle forEach. Les téléspectateurs peuvent obtenir une réponse trompeuse.

1105voto

Rok Kralj Points 11593

Si vous préférez une solution qui ne nécessite pas l'initialisation du compteur en dehors de la boucle, je propose de comparer la clé de l'itération en cours avec la fonction qui vous indique la dernière / première clé du tableau.

Cela devient un peu plus efficace (et plus lisible) avec la prochaine version de PHP 7.3.

Solution pour PHP 7.3 et plus :

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

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

Solution pour toutes les versions de PHP :

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

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

50 votes

Une réponse fantastique ! Beaucoup plus propre que l'utilisation d'un tas de tableaux.

14 votes

Cette réponse devrait remonter jusqu'en haut parce qu'elle est la bonne. Un autre avantage de ces fonctions par rapport à l'utilisation de array_shift et array_pop est que les tableaux restent intacts, au cas où ils seraient nécessaires ultérieurement. +1 pour le partage des connaissances juste pour le plaisir de le faire.

1 votes

Cela devrait faire des bulles jusqu'en haut car c'est le plus propre !

471voto

Gumbo Points 279147

Tu pourrais utiliser un compteur :

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

26 votes

Je ne pense pas que le downvoting doive avoir lieu ici, car cette méthode fonctionne également correctement et n'est pas aussi mauvaise que l'utilisation de l'outil de gestion de l'information. array_shift et array_pop . Bien que ce soit la solution que j'aurais trouvée si je devais mettre en œuvre une telle chose, je m'en tiendrais à l'option Rok Kralj répondre maintenant.

17 votes

Si j'ai besoin d'un compteur, je préfère utiliser la boucle FOR au lieu de FOREACH.

13 votes

Si vous utilisez $i = 1 vous n'avez pas à vous soucier $len - 1 il suffit d'utiliser $len .

128voto

Yojance Points 26

Pour trouver le dernier élément, je trouve que ce morceau de code fonctionne à chaque fois :

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

2 votes

Il y a trop peu de votes positifs. Y a-t-il un inconvénient à utiliser cette méthode ?

2 votes

@Kevin Kuyl - Comme mentionné par Pang ci-dessus, si le tableau contient un élément que PHP évalue comme faux (i.e. 0, "", null) cette méthode aura des résultats inattendus. J'ai modifié le code pour utiliser ===

94voto

Hayden Points 401

Une version plus simplifiée de ce qui précède et en supposant que vous n'utilisez pas d'index personnalisés...

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

Version 2 - Parce que j'en suis venu à détester l'utilisation de l'autre sauf si nécessaire.

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

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

8 votes

Cela fonctionne aussi pour les objets. Les autres solutions ne fonctionnent que pour les tableaux.

1 votes

C'est la meilleure réponse pour moi mais elle devrait être condensée, il est inutile de déclarer la longueur en dehors de la boucle foreach : if ($index == count($array)-1){ ... }

2 votes

@Andrew de cette façon, vous continuez à compter les éléments du tableau, pour chaque itération.

40voto

Carlos Lima Points 2579

Vous pourriez retirer le premier et le dernier élément du tableau et les traiter séparément.

Comme ça :

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

La suppression de tout le formatage en CSS au lieu des balises en ligne améliorerait votre code et accélérerait le temps de chargement.

Vous pouvez également éviter de mélanger HTML et logique php dans la mesure du possible.

Votre page pourrait être beaucoup plus lisible et facile à entretenir en séparant les choses de cette manière :

<?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 votes

J'aime l'idée de dernier (en supprimant le dernier élément du tableau), de sorte que je puisse générer le dernier élément différemment sans vérifier à chaque boucle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X