Trouver le dernier élément d'un tableau en utilisant une boucle foreach en PHP

J'écris un créateur de requête SQL en utilisant certains paramètres. En Java, il est très facile de détecter le dernier élément d'un tableau à l'intérieur de la boucle for en vérifiant simplement la position actuelle du tableau avec la longueur du tableau.

for(int i=0; i< arr.length;i++){
     boolean isLastElem = i== (arr.length -1) ? true : false;        
}

En PHP, ils ont des index non entiers pour accéder aux tableaux. Vous devez donc itérer sur un tableau en utilisant une boucle foreach. Cela devient problématique lorsque vous devez prendre une décision (dans mon cas pour ajouter ou/et paramètre lors de la construction de la requête).

Je suis sûr il doit y avoir une manière standard de le faire.

Comment résolvez - vous cela en PHP?

177
demandé sur Thamilan 2009-03-20 09:01:27

29 réponses

On dirait que vous voulez quelque chose comme ceci:

$numItems = count($arr);
$i = 0;
foreach($arr as $key=>$value) {
  if(++$i === $numItems) {
    echo "last index!";
  }
}    

Cela étant dit, vous n'avez pas à itérer sur un "tableau" en utilisant foreach en php.

262
répondu Richard Levasseur 2012-06-10 22:01:40

Vous pouvez obtenir la valeur de la dernière clé du tableau en utilisant end(array_keys($array)) et la comparer à la clé actuelle:

$last_key = end(array_keys($array));
foreach ($array as $key => $value) {
    if ($key == $last_key) {
        // last element
    } else {
        // not last element
    }
}
177
répondu Jeremy Ruten 2009-03-20 06:07:08

Pourquoi si compliqué?

foreach($input as $key => $value) {
    $ret .= "$value";
    if (next($input)==true) $ret .= ",";
}

Cela ajoutera un, derrière chaque valeur sauf la dernière!

36
répondu Trikks 2009-12-14 14:52:04

Quand toEnd atteint 0, cela signifie qu'il est à la dernière itération de la boucle.

$toEnd = count($arr);
foreach($arr as $key=>$value) {
  if (0 === --$toEnd) {
    echo "last index! $value";
  }
}

, La dernière valeur est toujours disponible après la boucle, donc si vous voulez l'utiliser pour des choses plus après la boucle, c'est mieux:

foreach($arr as $key=>$value) {
  //something
}
echo "last index! $key => $value";

Si vous ne voulez pas traiter la dernière valeur comme des boucles intérieures spéciales. Cela devrait être plus rapide si vous avez de grands tableaux. (Si vous réutilisez le tableau après la boucle dans la même portée, vous devez d'abord "copier" le tableau).

//If you use this in a large global code without namespaces or functions then you can copy the array like this:
//$array = $originalArrayName; //uncomment to copy an array you may use after this loop

//end($array); $lastKey = key($array); //uncomment if you use the keys
$lastValue = array_pop($array);

//do something special with the last value here before you process all the others?
echo "Last is $lastValue", "\n";

foreach ($array as $key => $value) {
    //do something with all values before the last value
    echo "All except last value: $value", "\n";
}

//do something special with the last value here after you process all the others?
echo "Last is $lastValue", "\n";

Et de répondre à votre question originale "dans mon cas pour ajouter ou/et paramètre lors de la construction de la requête"; cela va faire une boucle sur toutes les valeurs, puis les joindre à une chaîne avec " et " entre eux mais pas avant la première valeur ou après la dernière valeur:

$params = [];
foreach ($array as $value) {
    $params[] = doSomething($value);
}
$parameters = implode(" and ", $params);
21
répondu OIS 2015-02-26 15:40:09

Il y a déjà beaucoup de réponses, mais il vaut la peine de regarder dans les itérateurs, d'autant plus qu'il a été demandé de manière standard:

$arr = range(1, 3);

$it = new CachingIterator(new ArrayIterator($arr));
foreach($it as $key => $value)
{
  if (!$it->hasNext()) echo 'Last:';
  echo $value, "\n";
}

Vous pourriez trouver quelque chose qui fonctionne plus flexible pour d'autres cas, aussi.

19
répondu hakre 2011-10-11 01:25:05

Donc, si votre tableau a des valeurs de tableau uniques, la détermination de la dernière itération est triviale:

foreach($array as $element) {
    if ($element === end($array))
        echo 'LAST ELEMENT!';
}

Comme vous le voyez, cela fonctionne si le dernier élément n'apparaît qu'une seule fois dans le tableau, sinon vous obtenez une fausse alerte. Dans ce n'est pas, vous devez comparer les clés (qui sont uniques à coup sûr).

foreach($array as $key => $element) {
    end($array);
    if ($key === key($array))
        echo 'LAST ELEMENT!';
}

Notez également l'opérateur de coparision strict, ce qui est très important dans ce cas.

7
répondu Rok Kralj 2012-04-21 07:11:59

En Supposant que vous avez le tableau stocké dans une variable...

foreach($array as $key=>$value) 
{ 
    echo $value;
    if($key != count($array)-1) { echo ", "; }
}
5
répondu Martin Heisterkamp 2012-10-09 11:38:27

Une façon peut être de détecter si l'itérateur a next. S'il n'y a pas de next attaché à l'itérateur, cela signifie que vous êtes dans la dernière boucle.

foreach ($some_array as $element) {
    if(!next($some_array)) {
         // This is the last $element
    }
}
5
répondu Raheel Khan 2017-10-18 16:37:42

Si vous devez faire quelque chose pour chaque élément sauf le premier ou le dernier et seulement s'il y a plus d'un élément dans le tableau, je préfère la solution suivante.

Je sais qu'il y a beaucoup de solutions ci-dessus et affichées des mois/un an avant la mienne, mais c'est quelque chose que je pense être assez élégant en soi. La vérification de chaque boucle est également une vérification booléenne par opposition à une vérification numérique "i=(count-1)", ce qui peut permettre moins de surcharge.

La structure de la boucle peut sentez-vous maladroit, mais vous pouvez le comparer à l'ordre de thead (début), tfoot (fin), tbody (courant) dans les balises de table HTML.

$first = true;
foreach($array as $key => $value) {
    if ($first) {
        $first = false;
        // Do what you want to do before the first element
        echo "List of key, value pairs:\n";
    } else {
        // Do what you want to do at the end of every element
        // except the last, assuming the list has more than one element
        echo "\n";
    }
    // Do what you want to do for the current element
    echo $key . ' => ' . $value;
}

Par exemple, en termes de développement web, si vous voulez ajouter un border-bottom à chaque élément sauf le dernier dans une liste non ordonnée (ul), vous pouvez plutôt Ajouter un border-top à chaque élément sauf le premier (le CSS: first-child, supporté par IE7+ et Firefox / Webkit supporte cette logique, alors que: last-child IE7).

Vous pouvez également réutiliser la variable $first pour chaque boucle imbriquée et les choses fonctionneront très bien puisque chaque boucle fait $first false pendant le premier processus de la première itération (donc les pauses / exceptions ne causeront pas de problèmes).

$first = true;
foreach($array as $key => $subArray) {
    if ($first) {
        $string = "List of key => value array pairs:\n";
        $first = false;
    } else {
        echo "\n";
    }

    $string .= $key . '=>(';
    $first = true;
    foreach($subArray as $key => $value) {
        if ($first) {
            $first = false;
        } else {
            $string .= ', ';
        }
        $string .= $key . '=>' . $value;
    }
    $string .= ')';
}
echo $string;

Exemple de sortie:

List of key => value array pairs:
key1=>(v1_key1=>v1_val1, v1_key2=>v1_val2)
key2=>(v2_key1=>v2_val1, v2_key2=>v2_val2, v2_key3=>v2_val3)
key3=>(v3_key1=>v3_val1)
4
répondu Ankit Aggarwal 2010-03-26 15:56:34

Cela devrait être le moyen facile de trouver le dernier élément:

foreach ( $array as $key => $a ) {
    if ( end( array_keys( $array ) ) == $key ) {
        echo "Last element";
     } else {
        echo "Just another element";
     }
}  

Référence : Lien

4
répondu Duli 2014-05-22 10:42:32

Vous pouvez toujours utiliser cette méthode avec des tableaux associatifs:

$keys = array_keys($array);
for ($i = 0, $l = count($array); $i < $l; ++$i) {
    $key = $array[$i];
    $value = $array[$key];
    $isLastItem = ($i == ($l - 1));
    // do stuff
}

// or this way...

$i = 0;
$l = count($array);
foreach ($array as $key => $value) {
    $isLastItem = ($i == ($l - 1));
    // do stuff
    ++$i;
}
3
répondu nickf 2009-03-20 06:54:57

J'ai un fort sentiment qu'à la racine de ce "problème XY" L'OP voulait juste la fonction implode().

3
répondu Your Common Sense 2012-04-21 07:22:18

Comme votre intention de trouver le tableau EOF est juste pour la colle. Présentez-vous à la tactique ci-dessous. Vous n'avez pas besoin de l'EOF:

$given_array = array('column1'=>'value1',
                     'column2'=>'value2',
                     'column3'=>'value3');

$glue = '';
foreach($given_array as $column_name=>$value){
    $where .= " $glue $column_name = $value"; //appending the glue
    $glue   = 'AND';
}
echo $where;

O / p:

column1 = value1 AND column2 = value2 AND column3 = value3
3
répondu Angelin Nadar 2013-04-06 05:36:39

Il semble que vous voulez quelque chose comme ceci:

$array = array(
    'First',
    'Second',
    'Third',
    'Last'
);

foreach($array as $key => $value)
{
    if(end($array) === $value)
    {
       echo "last index!" . $value;
    }
}
2
répondu Ashique CM 2011-09-22 06:47:13

, Vous pouvez faire un count().

for ($i=0;$i<count(arr);$i++){
    $i == count(arr)-1 ? true : false;
}

Ou si vous ne cherchez que le dernier élément, vous pouvez utiliser end ().

end(arr);

Renvoie uniquement le dernier élément.

Et, comme il s'avère, vous pouvez indexer les tableaux php par des entiers. Il est parfaitement heureux avec

arr[1];
1
répondu helloandre 2009-03-20 06:05:26

Que diriez-vous d'utiliser "end"? http://php.net/manual/en/function.end.php

1
répondu Çağ 2010-06-08 13:48:07

Vous pouvez aussi faire quelque chose comme ceci:

end( $elements );
$endKey = key($elements);
foreach ($elements as $key => $value)
{
     if ($key == $endKey) // -- this is the last item
     {
          // do something
     }

     // more code
}
1
répondu KOGI 2011-03-28 20:17:36

J'aime un peu ce qui suit car je pense que c'est assez soigné. Supposons que nous créons une chaîne avec des séparateurs entre tous les éléments: par exemple a,b, c

$first = true;
foreach ( $items as $item ) {
    $str = ($first)?$first=false:", ".$item;
}
1
répondu Alastair Brayne 2013-07-16 17:28:16

Voici une autre façon de le faire:

$arr = range(1, 10);

$end = end($arr);
reset($arr);

while( list($k, $v) = each($arr) )
{
    if( $n == $end )
    {
        echo 'last!';
    }
    else
    {
        echo sprintf('%s ', $v);
    }
}
0
répondu Kevin 2009-12-09 23:52:31

Si je vous comprends, alors tout ce dont vous avez besoin est d'inverser le tableau et d'obtenir le dernier élément par une commande pop:

   $rev_array = array_reverse($array);

   echo array_pop($rev_array);
0
répondu James 2010-04-08 16:13:41

Vous pouvez également essayer ceci pour faire votre requête... montré ici avec INSERT

<?php
 $week=array('one'=>'monday','two'=>'tuesday','three'=>'wednesday','four'=>'thursday','five'=>'friday','six'=>'saturday','seven'=>'sunday');
 $keys = array_keys($week);
 $string = "INSERT INTO my_table ('";
 $string .= implode("','", $keys);
 $string .= "') VALUES ('";
 $string .= implode("','", $week);
 $string .= "');";
 echo $string;
?>
0
répondu Mark 2010-11-05 20:27:45

Pour les scripts de génération de requêtes SQL, ou tout ce qui fait une action différente pour le premier ou le dernier élément, il est beaucoup plus rapide (presque deux fois plus rapide) d'éviter d'utiliser des vérifications de variables inutiles.

La solution acceptée actuelle utilise une boucle et une vérification dans la boucle qui sera faite every_single_iteration, la manière correcte (rapide) de le faire est la suivante:

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

Un petit benchmark fait maison a montré ce qui suit:

Test1: 100000 courses de modèle morg

Temps: 1869.3430423737 millisecondes

Test2: 100000 essais du modèle si dernier

Temps: 3235.6359958649 millisecondes

0
répondu Morg. 2011-08-09 13:29:14

Une autre façon de procéder est de se souvenir du résultat du cycle de boucle précédent et de l'utiliser comme résultat final:

    $result = $where = "";
    foreach ($conditions as $col => $val) {
        $result = $where .= $this->getAdapter()->quoteInto($col.' = ?', $val);
        $where .=  " AND ";
    }
    return $this->delete($result);
0
répondu Leven 2012-03-11 21:52:28

Personnellement, j'utilise ce type de construction qui permet une utilisation facile avec les éléments html et : il suffit de changer l'égalité pour une autre propriété...

Le tableau ne peut pas contenir de faux éléments mais tous les autres éléments qui sont convertis dans le faux booléen.

$table = array( 'a' , 'b', 'c');
$it = reset($table);
while( $it !== false ) {
    echo 'all loops';echo $it;
    $nextIt = next($table);
    if ($nextIt === false || $nextIt === $it) {
            echo 'last loop or two identical items';
    }
    $it = $nextIt;
}
0
répondu MUY Belgium 2012-07-30 11:34:00

Vous pouvez directement obtenir le dernier index par:

$numItems = count($arr);

echo $arr[$numItems-1];

0
répondu Denis Omeri 2012-08-16 13:59:23
<?php foreach($have_comments as $key => $page_comment): ?>
    <?php echo $page_comment;?>
    <?php if($key+1<count($have_comments)): ?> 
        <?php echo ', '; ?>
    <?php endif;?>
<?php endforeach;?>
0
répondu Zarpele 2012-11-21 14:19:01

Voici ma solution: Obtenez simplement le nombre de votre tableau, moins 1 (puisqu'ils commencent en 0).

$lastkey = count($array) - 1;
foreach($array as $k=>$a){
    if($k==$lastkey){
        /*do something*/
    }
}
0
répondu ITWitch 2016-10-22 08:04:38
foreach ($array as $key => $value) {

  $class = ( $key !== count( $array ) -1 ) ? " class='not-last'" : " class='last'";

  echo "<div{$class}>";
  echo "$value['the_title']";
  echo "</div>";

}

Référence

0
répondu Ayman Elshehawy 2018-09-23 13:10:17

J'ai une solution généralisée que j'utilise, dans le but commun de compiler une chaîne à partir d'un tableau de valeurs de chaîne. Tout ce que je fais est d'ajouter une chaîne inhabituelle à la fin, puis de la remplacer.

Fonction Pour renvoyer une chaîne d'un tableau, séparée, sans séparateur de fin:

function returnArraySeparated($aArr, $sSep, $sAdd = "@X@") {

$strReturn = (string) "";


# Compile the set:
foreach ($aArr as $sItem) {
    $strReturn .= $sItem . $sSep;
}

# Easy strip the end:
$strReturn = str_replace($sSep . $sAdd, "", $strReturn . $sAdd);

return $strReturn;
}

Rien de spécial, mais ça marche:)

-3
répondu Rich Harding 2011-11-19 20:47:09