Quelle est la meilleure façon d'obtenir le dernier élément d'un tableau sans le supprimer?


427

D'accord,

Je sais tout array_pop(), mais cela supprime le dernier élément. Quelle est la meilleure façon d'obtenir le dernier élément d'un tableau sans le supprimer?

EDIT: Voici un bonus:

$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');

ou même

$array = array('a', 'b', 'c', 'd');
unset($array[2]);
echo $array[sizeof($array) - 1]; // Output: PHP Notice:  Undefined offset:  2 in - on line 4

11
Croyez-le ou ne pas le faire éclater et le remettre en place est l'un des moyens les plus rapides pour lequel je l'ai fait. $ val = $ array [] = array_pop ($ array); echo $ val;
user2782001

2
Cette question a donné lieu à de nombreuses options. Pour m'aider à choisir, j'ai comparé les options les plus notables / distinctes et partagé les résultats en tant que réponse distincte . (: @ user2782001 a suggéré mon préféré jusqu'à présent dans le commentaire ci-dessus. :) Merci à tous pour votre contribution!
Paul van Leeuwen

1
@TheodoreRSmith Lorsque PHP 7.3 est disponible , vous pouvez envisager de faire ( cette suggestion par le clone de Quasimodo la « réponse acceptée » (pour examen) ...
Paul van Leeuwen

Réponses:


176

Les nombreuses réponses de ce fil nous présentent de nombreuses options différentes. Pour pouvoir choisir parmi eux, j'avais besoin de comprendre leur comportement et leurs performances. Dans cette réponse , je vais partager mes découvertes avec vous, étalonnées par rapport versions PHP 5.6.38, 7.2.10et 7.3.0RC1( prévu le 13 décembre 2018 ).

Les options que <<option code>>je vais tester sont:

(fonctions mentionnées: array_key_last , array_keys , array_pop , array_slice , array_values , count , end , reset )

Les entrées de test <<input code>>à combiner avec:

  • null =$array = null;
  • vide =$array = [];
  • last_null =$array = ["a","b","c",null];
  • auto_idx =$array = ["a","b","c","d"];
  • shuffle =$array = []; $array[1] = "a"; $array[2] = "b"; $array[0] = "c";
  • 100 =$array = []; for($i=0;$i<100;$i++) { $array[] = $i; }
  • 100000 =$array = []; for($i=0;$i<100000;$i++) { $array[] = $i; }

Pour tester , je vais utiliser le 5.6.38, 7.2.10et les 7.3.0RC1 conteneurs PHP docker comme:

sudo docker run -it --rm php:5.6.38-cli-stretch php -r '<<<CODE HERE>>>'

Chaque combinaison des <<option code>>s et <<input code>>s listés ci-dessus sera exécutée sur toutes les versions de PHP. Pour chaque test, l'extrait de code suivant est utilisé:

<<input code>>  error_reporting(E_ALL);  <<option code>>  error_reporting(0); $before=microtime(TRUE); for($i=0;$i<100;$i++){echo ".";for($j=0;$j<100;$j++){  <<option code>>  }}; $after=microtime(TRUE); echo "\n"; var_dump($x); echo round(($after-$before)/(100*100)*1000*1000*1000);

Pour chaque exécution, cela var_dump la dernière dernière valeur récupérée de l'entrée de test et affichera la durée moyenne d'une itération en femtosecondes (0,00000000000000001e de seconde).

Les résultats sont les suivants:

/==========================================================================================================================================================================================================================================================================================================================================================================================================================\
||                                                                      ||                            T  E  S  T     I  N  P  U  T     -     5  .  6  .  3  8                            ||                             T  E  S  T     I  N  P  U  T     -     7  .  2  .  1  0                           ||                             T  E  S  T     I  N  P  U  T     -     7  .  3  .  0  R  C  1                     ||
||                                                                      ||          null |         empty |     last_null |      auto_idx |       shuffle |           100 |        100000 ||          null |         empty |     last_null |      auto_idx |       shuffle |           100 |        100000 ||          null |         empty |     last_null |      auto_idx |       shuffle |           100 |        100000 ||
||============================OPTIONS - ERRORS==========================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
||  1.  $x = array_values(array_slice($array, -1))[0];                  ||       W1 + W2 |            N1 |             - |             - |             - |             - |             - ||       W1 + W2 |            N1 |             - |             - |             - |             - |             - ||       W1 + W2 |            N1 |             - |             - |             - |             - |             - ||
||  2.  $x = array_slice($array, -1)[0];                                ||            W1 |            N1 |             - |             - |             - |             - |             - ||            W1 |            N1 |             - |             - |             - |             - |             - ||            W1 |            N1 |             - |             - |             - |             - |             - ||
||  3.  $x = array_pop((array_slice($array, -1)));                      ||       W1 + W3 |             - |             - |             - |             - |             - |             - ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||
||  4.  $x = array_pop((array_slice($array, -1, 1)));                   ||       W1 + W3 |             - |             - |             - |             - |             - |             - ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||
||  5.  $x = end($array); reset($array);                                ||       W4 + W5 |             - |             - |             - |             - |             - |             - ||       W4 + W5 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||       W4 + W5 |             - |             - |             - |             - |             - |             - ||
||  6.  $x = end((array_values($array)));                               ||       W2 + W4 |             - |             - |             - |             - |             - |             - ||  W2 + N2 + W4 |             - |             - |             - |             - |             - |             - ||  W2 + N2 + W4 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||
||  7.  $x = $array[count($array)-1];                                   ||             - |            N3 |             - |             - |             - |             - |             - ||            W7 |            N3 |             - |             - |             - |             - |             - ||            W7 |            N3 |             - |             - |             - |             - |             - ||
||  8.  $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; ||            W6 |       N3 + N4 |             - |             - |             - |             - |             - ||       W6 + W7 |       N3 + N4 |             - |             - |             - |             - |             - ||       W6 + W7 |       N3 + N4 |             - |             - |             - |             - |             - ||
||  9.  $x = $array[] = array_pop($array);                              ||            W3 |             - |             - |             - |             - |             - |             - ||            W3 |             - |             - |             - |             - |             - |             - ||            W3 |             - |             - |             - |             - |             - |             - ||
|| 10.  $x = $array[array_key_last($array)];                            ||            F1 |            F1 |            F1 |            F1 |            F1 |            F1 |            F1 ||            F2 |            F2 |            F2 |            F2 |            F2 |            F2 |            F2 ||            W8 |            N4 |            F2 |            F2 |            F2 |            F2 |            F2 ||
||========================OPTIONS - VALUE RETRIEVED=====================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
||  1.  $x = array_values(array_slice($array, -1))[0];                  ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  2.  $x = array_slice($array, -1)[0];                                ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  3.  $x = array_pop((array_slice($array, -1)));                      ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  4.  $x = array_pop((array_slice($array, -1, 1)));                   ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  5.  $x = end($array); reset($array);                                ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  6.  $x = end((array_values($array)));                               ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  7.  $x = $array[count($array)-1];                                   ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "b" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "b" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "b" |       int(99) |    int(99999) ||
||  8.  $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  9.  $x = $array[] = array_pop($array);                              ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
|| 10.  $x = $array[array_key_last($array)];                            ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||
||=================OPTIONS - FEMTOSECONDS PER ITERATION=================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
||  1.  $x = array_values(array_slice($array, -1))[0];                  ||           803 |           466 |           390 |           384 |           373 |           764 |     1.046.642 ||           691 |           252 |           101 |           128 |            93 |           170 |        89.028 ||           695 |           235 |            90 |            97 |            95 |           188 |        87.991 ||
||  2.  $x = array_slice($array, -1)[0];                                ||           414 |           349 |           252 |           248 |           246 |           604 |     1.038.074 ||           373 |           249 |            85 |            91 |            90 |           164 |        90.750 ||           367 |           224 |            78 |            85 |            80 |           155 |        86.141 ||
||  3.  $x = array_pop((array_slice($array, -1)));                      ||           724 |           228 |           323 |           318 |           350 |           673 |     1.042.263 ||           988 |           285 |           309 |           317 |           331 |           401 |        88.363 ||           877 |           266 |           298 |           300 |           326 |           403 |        87.279 ||
||  4.  $x = array_pop((array_slice($array, -1, 1)));                   ||           734 |           266 |           358 |           356 |           349 |           699 |     1.050.101 ||           887 |           288 |           316 |           322 |           314 |           408 |        88.402 ||           935 |           268 |           335 |           315 |           313 |           403 |        86.445 ||
||  5.  $x = end($array); reset($array);                                ||           715 |           186 |           185 |           180 |           176 |           185 |           172 ||           674 |            73 |            69 |            70 |            66 |            65 |            70 ||           693 |            65 |            85 |            74 |            68 |            70 |            69 ||
||  6.  $x = end((array_values($array)));                               ||           877 |           205 |           320 |           337 |           304 |         2.901 |     7.921.860 ||           948 |           300 |           336 |           308 |           309 |           509 |    29.696.951 ||           946 |           262 |           301 |           309 |           302 |           499 |    29.234.928 ||
||  7.  $x = $array[count($array)-1];                                   ||           123 |           300 |           137 |           139 |           143 |           140 |           144 ||           312 |           218 |            48 |            53 |            45 |            47 |            51 ||           296 |           217 |            46 |            44 |            53 |            53 |            55 ||
||  8.  $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; ||           494 |           593 |           418 |           435 |           399 |         3.873 |    12.199.450 ||           665 |           407 |           103 |           109 |           114 |           431 |    30.053.730 ||           647 |           445 |            91 |            95 |            96 |           419 |    30.718.586 ||
||  9.  $x = $array[] = array_pop($array);                              ||           186 |           178 |           175 |           188 |           180 |           181 |           186 ||            83 |            78 |            75 |            71 |            74 |            69 |            83 ||            71 |            64 |            70 |            64 |            68 |            69 |            81 ||
|| 10.  $x = $array[array_key_last($array)];                            ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           370 |           223 |            49 |            52 |            61 |            57 |            52 ||
 \=========================================================================================================================================================================================================================================================================================================================================================================================================================/ 

Mentionné ci - dessus F Atal, W vertissement et N VIS codes se traduisent par:

F1 = Fatal error: Call to undefined function array_key_last() in Command line code on line 1
F2 = Fatal error: Uncaught Error: Call to undefined function array_key_last() in Command line code:1
W1 = Warning: array_slice() expects parameter 1 to be array, null given in Command line code on line 1
W2 = Warning: array_values() expects parameter 1 to be array, null given in Command line code on line 1
W3 = Warning: array_pop() expects parameter 1 to be array, null given in Command line code on line 1
W4 = Warning: end() expects parameter 1 to be array, null given in Command line code on line 1
W5 = Warning: reset() expects parameter 1 to be array, null given in Command line code on line 1
W6 = Warning: array_keys() expects parameter 1 to be array, null given in Command line code on line 1
W7 = Warning: count(): Parameter must be an array or an object that implements Countable in Command line code on line 1
W8 = Warning: array_key_last() expects parameter 1 to be array, null given in Command line code on line 1
N1 = Notice: Undefined offset: 0 in Command line code on line 1
N2 = Notice: Only variables should be passed by reference in Command line code on line 1
N3 = Notice: Undefined offset: -1 in Command line code on line 1
N4 = Notice: Undefined index:  in Command line code on line 1

Sur la base de ce résultat, je tire les conclusions suivantes:

  • les versions plus récentes de PHP fonctionnent mieux à l'exception de ces options qui sont devenues beaucoup plus lentes:
    • option .6. $x = end((array_values($array)));
    • option .8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
  • ces options s'adaptent mieux aux très grands tableaux:
    • option .5. $x = end($array); reset($array);
    • option .7. $x = $array[count($array)-1];
    • option .9. $x = $array[] = array_pop($array);
    • option 10. $x = $array[array_key_last($array)]; (depuis PHP 7.3)
  • ces options ne doivent être utilisées que pour les tableaux auto-indexés :
    • option .7. $x = $array[count($array)-1];(en raison de l'utilisation decount)
    • option .9. $x = $array[] = array_pop($array);(en raison de l'attribution d'une valeur en perdant la clé d'origine)
  • cette option ne conserve pas le pointeur interne du tableau
    • option .5. $x = end($array); reset($array);
  • cette option est une tentative de modification de l' option .5. pour préserver le pointeur interne du tableau (mais malheureusement, il ne s'adapte pas bien aux très grands tableaux)
    • option .6. $x = end((array_values($array)));
  • la nouvelle array_key_lastfonction ne semble avoir aucune des limitations mentionnées ci-dessus à l'exception d'être toujours un RC au moment de la rédaction de cet article (alors utilisez le RC ou attendez sa sortie en décembre 2018):
    • option 10. $x = $array[array_key_last($array)]; (depuis PHP 7.3)

Un peu selon que vous utilisez le tableau comme pile ou comme file d'attente, vous pouvez faire des variations sur l'option 9.


Si vous trouvez qu'une option particulière manque, vous pouvez la tester vous-même en copiant-collant les extraits de code ci-dessus, en la comparant à une option précédemment testée. Ajouter une option à cette liste revérifierait toutes les combinaisons pour des résultats de performances comparables. Si vous pensez qu'une option particulière devrait être ajoutée, veuillez laisser un commentaire, j'ai l'intention de l'ajouter ensuite (bien que cela puisse prendre un certain temps).
Paul van Leeuwen

1
Très bonne réponse, un commentaire cependant: pour les tableaux associatifs, l'option 9 ne peut pas être utilisée également, car nous attribuons de nouveau une clé auto-indexée au lieu du nom de la clé précédente.
Gras Double

1
Joli résumé! Veuillez ajouter ma réponse en utilisant le nouveau PHP 7.3. fonction $array[array_key_last($array)];de votre référence. Et veuillez me donner une notification lorsque vous avez terminé. J'aimerais voir les résultats de performance en comparaison.
Le clone de Quasimodo

2
@sz, il a été principalement produit avec beaucoup d'entêtement et de patience, mais la sélection générale et les fonctions d'édition sur plusieurs lignes de l'éditeur de texte Sublime ont aidé. sa régénération a pris près d'une journée, donc si je dois le refaire, j'écrirai probablement quelque chose qui convertira automatiquement la sortie des 210 exécutions de docker en une table :-)
Paul van Leeuwen

1
@ quasimodos-clone J'ai régénéré la table entière sur la base des dernières versions de PHP 5, 7 et de votre RC. Je suppose que nous voudrons le générer à nouveau en décembre, lors de sa sortie. Merci d'avoir porté cette nouvelle fonction à l'attention de tous.
Paul van Leeuwen

487

Essayer

$myLastElement = end($yourArray);

Pour le réinitialiser (merci @hopeseekr):

 reset($yourArray);

Lien vers le manuel

@David Murdoch a ajouté: $myLastElement = end(array_values($yourArray));// and now you don't need to call reset(). sur E_STRICT cela produit l'avertissement

Strict Standards: Only variables should be passed by reference

Merci o_O Tync et tout le monde!


38
Utilisez $myLastElement = end(array_values($yourArray));et maintenant vous n'avez pas besoin d'appeler reset().
David Murdoch

5
@DavidMurdoch Peut-être, mais cela remue certainement la RAM et le CPU, créant le tableau temporaire pour les valeurs du tableau ...
Theodore R. Smith

12
Si votre serveur consomme trop de RAM pour que l'appel à une fonction supplémentaire simple soit un facteur de rupture, je vous suggère de réexaminer la configuration et les ressources de votre serveur.
Chris Baker

3
end(array_values())donnera un E_STRICT: "Seules les variables doivent être passées par référence"
kolypto

32
Ajoutez des parenthèses supplémentaires pour éviter l'avertissement strict:end((array_values($yourArray)))
Daniel W.

212

Court et doux.

J'ai trouvé une solution pour supprimer les messages d'erreur et préserver la forme à une ligne et les performances efficaces:

$lastEl = array_values(array_slice($array, -1))[0];

- solution précédente

$lastEl = array_pop((array_slice($array, -1)));

Remarque: Les parenthèses supplémentaires sont nécessaires pour éviter a PHP Strict standards: Only variables should be passed by reference.


31
Après exactement 5 ans, 6 mois et 2 jours, vous avez soumis une réponse plus supérieure !! Je vous remercie! et merci Stack Overflow !!
Theodore R. Smith

1
Bonne réponse, mais l'ajout de parenthèses supplémentaires semble un peu hackisch. PhpStorm marquera également cela comme une erreur. Informations supplémentaires pour ajouter des parenthèses supplémentaires ( phpsadness.com/sad/51 ). Pour surmonter l'erreur, vous pouvez en faire un «2 lignes»: $array = array_slice($array, -1); $lastEl = array_pop($array);Personnellement, je pense que c'est mieux (sans le «bug» de l'analyseur)
Maurice

3
Vous pouvez utiliser le déréférencement comme ceci: array_slice ($ array, -1) [0]
Vikash

1
Vous ne pouvez pas si vous avez des chaînes comme index dans un tableau
rolacja

3
Cette réponse nécessite toujours au moins deux vérifications pour éviter les notifications PHP. 1. Vérifiez si le array_size() > 1 2. Vérifiez si le tableau est réellement un tableau. Je reste fidèle à la réponse de @Iznogood, car la fonction intégrée de PHP end()fait déjà tout le travail de manière plus efficace.
Ema4rl

37

Qu'est-ce qui ne va pas array_slice($array, -1)? (Voir le manuel: http://us1.php.net/array_slice )

array_slice()renvoie un tableau. Probablement pas ce que vous cherchez. Vous voulez l'élément.


21
Utilisez array_slice($array, -1)[0]pour obtenir l'élément.
Pang

2
Telle est la réponse. "end" Changer le pointeur interne du tableau? Demander des ennuis, et très difficile à lire!
Gerard ONeill

J'adore cette approche, même si, comme le souligne @Pang, elle n'est pas tout à fait complète. reset(array_slice($array, -1))est une autre approche (qui ne provoquera pas d'erreur si array_slice()renvoie quelque chose de "plus petit" qu'un tableau à un seul élément)
rinogo

La meilleure approche car vous pouvez directement modifier l'élément:array_slice($array, -1)[0] = "";
HAlex

20

Une façon d'éviter les erreurs de passage par référence (par exemple "end (array_values ​​($ foo))")) consiste à utiliser call_user_func ou call_user_func_array:

// PHP Fatal error: Only variables can be passed by reference
// No output (500 server error)
var_dump(end(array(1, 2, 3)));

// No errors, but modifies the array's internal pointer
// Outputs "int(3)"
var_dump(call_user_func('end', array(1, 2, 3)));

// PHP Strict standards:  Only variables should be passed by reference
// Outputs "int(3)"
var_dump(end(array_values(array(1, 2, 3))));

// No errors, doesn't change the array
// Outputs "int(3)"
var_dump(call_user_func('end', array_values(array(1, 2, 3))));

Super approche! (insérer ici la norme 'Ceci devrait être la réponse acceptée')
Typo

3
Ou ajoutez simplement une paranthèse supplémentaire. Plus court et plus doux:end((array_values($yourArray)))
Dzhuneyt

4
L'astuce de parenthèse supplémentaire repose sur un bogue en PHP, et cette approche ne fonctionne plus dans les versions ultérieures de PHP (ou du moins, pas en PHP 7).
Matt Browne

1
Et l' call_user_funcastuce ne fonctionne pas non plus en PHP 7. Je pense que vous êtes coincé avec la création d'une variable temporaire.
Matt Browne

15

Si vous ne vous souciez pas de modifier le pointeur interne (prend en charge les tableaux indexés et associatifs):

// false if empty array
$last = end($array);

// null if empty array
$last = !empty($array) ? end($array) : null;


Si vous voulez une fonction utilitaire qui ne modifie pas le pointeur interne (car le tableau est passé par valeur et la fonction fonctionne sur une copie de celui-ci):

function array_last($array) {
    if (empty($array)) {
        return null;
    }
    return end($array);
}

Notez que PHP produit des copies "à la volée", c'est-à-dire uniquement lorsque cela est réellement nécessaire. Le end()lui-même modifie le tableau, donc en interne une copie du tableau est générée.


Ainsi, l'alternative suivante est en fait plus rapide car en interne, elle ne copie pas le tableau, elle fait juste une tranche:

function array_last($array) {
    if (empty($array)) {
        return null;
    }
    foreach (array_slice($array, -1) as $value) {
        return $value;
    }
}

Ce "foreach / return" est un ajustement pour obtenir efficacement le premier (et ici unique) article.


Enfin, l'alternative la plus rapide mais uniquement pour les tableaux indexés:

$last = !empty($array) ? $array[count($array)-1] : null;



Pour mémoire, voici une autre réponse à moi , pour le premier élément du tableau.


vous fournissez 2 implémentations alternatives pour une array_lastfonction. Pour le premier, vous déclarez que le $arrayest copié et pour le second qu'il n'est pas copié. Quelle est la différence / pourquoi est-elle copiée dans la première implémentation et non dans la seconde?
Paul van Leeuwen

1
@PaulvanLeeuwen J'ai compris pourquoi vous étiez confus. J'ai essayé de clarifier la réponse , est-ce mieux?
Gras Double

10

non testé: cela ne fonctionnerait-il pas?

<?php
$last_element=end(array_values($array));
?>

Puisque le tableau retourné par array_values ​​est éphémère, personne ne se soucie si son pointeur est réinitialisé.

et si vous avez besoin de la clé pour aller avec, je suppose que vous feriez:

<?php
$last_key=end(array_keys($array));
?>

9

J'en ai besoin assez souvent pour gérer les piles, et je suis toujours déconcerté par le fait qu'il n'y a pas de fonction native qui le fasse sans manipuler le tableau ou son pointeur interne sous une forme ou une autre.

Donc, je porte généralement une fonction util qui est également sûre à utiliser sur des tableaux associatifs.

function array_last($array) {
    if (count($array) < 1)
        return null;

    $keys = array_keys($array);
    return $array[$keys[sizeof($keys) - 1]];
}

1
Bonne nouvelle, ils en font une fonction native :-) Vous pouvez garder un œil sur la planification de sa sortie ici: wiki.php.net/todo/php73 (attendu le 13 décembre 2018 au moment de la rédaction de cet article).
Paul van Leeuwen

9

Pour obtenir le dernier élément d'un tableau, utilisez:

$lastElement = array_slice($array, -1)[0];

Référence

J'ai répété 1 000 fois, en saisissant le dernier élément des petits et des grands tableaux contenant respectivement 100 et 50 000 éléments.

Method: $array[count($array)-1];
Small array (s): 0.000319957733154
Large array (s): 0.000526905059814
Note: Fastest!  count() must access an internal length property.
Note: This method only works if the array is naturally-keyed (0, 1, 2, ...).

Method: array_slice($array, -1)[0];
Small array (s): 0.00145292282104
Large array (s): 0.499367952347

Method: array_pop((array_slice($array, -1, 1)));
Small array (s): 0.00162816047668
Large array (s): 0.513121843338

Method: end($array);
Small array (s): 0.0028350353241
Large array (s): 4.81077480316
Note: Slowest...

J'ai utilisé PHP version 5.5.32.


qu'en est-il de l'utilisation de $ array [array_keys ($ array) [count (array_keys ($ array)) - 1]]?
user2782001

hmm..array_keys semble évoluer assez mal.
user2782001

1
Il est en fait plus rapide pour le grand tableau (0,0002) de faire apparaître l'élément et de le remettre sur ... $ val = $ ar [] = $ array_pop ($ ar);
user2782001

1
@ Westy92 Vos unités semblent mal sur la référence. Le plus petit nombre que vous donnez est 0,00031 ... microsecondes, soit environ 0,3 nanosecondes. Cela signifierait que votre test a pris un tick d'horloge à exécuter si vous avez un ordinateur récent. Je suppose que vous vouliez dire des millisecondes ou peut-être même des secondes .
Cesoid

1
Les valeurs sont clairement fausses de plusieurs ordres de grandeur. Pourquoi mettre l'accent sur la performance de toute façon?
istepaniuk

6

end () fournira le dernier élément d'un tableau

$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
echo end($array); //output: c

$array1 = array('a', 'b', 'c', 'd');
echo end($array1); //output: d

1
Cette solution fonctionne, mais elle change le pointeur interne du tableau, je ne pense pas que ce soit la bonne façon.
UnixAgain

5

Depuis PHP version 7.3, les fonctions array_key_firstetarray_key_last ont été introduites.

Étant donné que les tableaux en PHP ne sont pas des types de tableau stricts, c'est-à-dire des collections de taille fixe de champs de taille fixe commençant à l'index 0, mais un tableau associatif étendu dynamiquement, la gestion des positions avec des clés inconnues est difficile et les solutions de contournement ne fonctionnent pas très bien. En revanche, les tableaux réels seraient adressés en interne via l'arithmétique des pointeurs très rapidement et le dernier index est déjà connu au moment de la compilation par déclaration.

Au moins le problème avec la première et la dernière position est résolu par les fonctions intégrées depuis la version 7.3. Cela fonctionne même sans aucun avertissement sur les littéraux de tableau prêts à l'emploi:

$first = array_key_first( [1, 2, 'A'=>65, 'B'=>66, 3, 4 ] );
$last  = array_key_last ( [1, 2, 'A'=>65, 'B'=>66, 3, 4 ] );

Évidemment, la dernière valeur est:

$array[array_key_last($array)];

1
Merci d'avoir porté cela à l'attention de tous. Pour ceux qui sont désireux d'utiliser ceci: veuillez ne pas savoir qu'il s'agit d'un RC au moment de la rédaction de cet article. La sortie est prévue pour décembre 2018.
Paul van Leeuwen

1
C'est une super nouvelle. Je viens de publier un polyfill / shim dans ma réponse ci-dessous afin que les gens puissent commencer à utiliser cette syntaxe immédiatement.
Mark Thomson

3
$lastValue = end(array_values($array))

Aucune modification n'est apportée aux pointeurs $ array. Cela évite la

reset($array)

ce qui peut ne pas être souhaité dans certaines conditions.


3

Pour moi:

$last = $array[count($array) - 1];

Avec les associatifs:

$last =array_values($array)[count($array - 1)]

Veuillez fournir un contexte à votre réponse.
Shawn

2
@Shawn Quel contexte? Pas besoin de contexte. Ajout de code pour les tableaux associatifs.
Mirko Pagliai du

3

Les meilleures réponses sont excellentes, mais comme mentionné par @ paul-van-leeuwen et @ quasimodos-clone, PHP 7.3 introduira deux nouvelles fonctions pour résoudre directement ce problème - array_key_first () et array_key_last () .

Vous pouvez commencer à utiliser cette syntaxe dès aujourd'hui avec les fonctions polyfill (ou shim) suivantes.

// Polyfill for array_key_last() available from PHP 7.3
if (!function_exists('array_key_last')) {
  function array_key_last($array) {
    return array_slice(array_keys($array),-1)[0];
  }
}

// Polyfill for array_key_first() available from PHP 7.3
if (!function_exists('array_key_first')) {
  function array_key_first($array) {
    return array_slice(array_keys($array),0)[0];
  }
}

// Usage examples:
$first_element_key   = array_key_first($array);
$first_element_value = $array[array_key_first($array)];

$last_element_key    = array_key_last($array);
$last_element_value  = $array[array_key_last($array)];

Attention: cela nécessite PHP 5.4 ou supérieur.


2

Pour ce faire et éviter l'E_STRICT et ne pas jouer avec le pointeur interne du tableau, vous pouvez utiliser:

function lelement($array) {return end($array);}

$last_element = lelement($array);

lelement ne fonctionne qu'avec une copie, cela n'affecte donc pas le pointeur du tableau.


2

Une autre solution:

$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
$lastItem = $array[(array_keys($array)[(count($array)-1)])];
echo $lastItem;

2

Une autre solution possible ...

$last_element = array_reverse( $array )[0];

Ne pas travailler sur des tableaux associatifs ne me semble pas être une raison suffisante pour revenir en arrière. En termes de qualité, cette réponse n'est pas pire que de nombreuses autres réponses à cette question. Je ne comprends pas pourquoi je vois au moins 2 downvotes en ce moment. (score de -2). Quoi qu'il en soit, vote positif pour moi, ce n'est pas si mal.
Paul van Leeuwen

2

Que diriez-vous:

current(array_slice($array, -1))
  • fonctionne pour les tableaux associatifs
  • fonctionne quand $array == [](retournefalse )
  • n'affecte pas le tableau d'origine

2

Vous obtiendrez facilement le dernier élément d'un tableau en utilisant la logique ci-dessous

$array = array('a', 'b', 'c', 'd');
echo ($array[count($array)-1]);

Non seulement le dernier élément, mais vous pouvez également obtenir l'avant-dernier, l'avant-dernier et ainsi de suite en utilisant la logique ci-dessous.

pour l'avant-dernier élément, vous devez passer juste le numéro 2 dans l'instruction ci-dessus, par exemple:
echo ($ array [count ($ array) -2]);


1

Pour obtenir la dernière valeur de Array:

array_slice($arr,-1,1) ;

Pour supprimer le dernier tableau de formulaire de valeur:

array_slice($arr,0,count($arr)-1) ;

1
array_slice($arr,-1,1)entraînera un autre tableau de longueur 1, pas le dernier élément
Vic

Prenons un exemple: $a=array("red","green","blue","yellow","brown"); print_r(array_slice($a,-1,1)); Résultat:Array ( [0] => brown )
Rishabh

1

Simplement: $last_element = end((array_values($array)))

Ne réinitialise pas la baie et ne donne pas d'avertissement STRICT.

PS. Étant donné que la réponse la plus votée n'a toujours pas la double parenthèse, j'ai soumis cette réponse.


1

Je pense que c'est une légère amélioration par rapport à toutes les réponses existantes:

$lastElement = count($array) > 0 ? array_values(array_slice($array, -1))[0] : null;
  • Performances supérieures à end()ou solutions utilisantarray_keys() , en particulier avec des baies de grande taille
  • Ne modifie pas le pointeur interne du tableau
  • N'essaiera pas d'accéder à un décalage indéfini pour les tableaux vides
  • Fonctionne comme prévu pour les tableaux vides, les tableaux indexés, les tableaux mixtes et les tableaux associatifs

Malheureusement, cela ne fonctionne pas avec les tableaux associatifs, car l'élément unique de la tranche peut avoir une clé nommée.
Gras Double

Vous avez raison, modifié pour ajouter un correctif ( array_valuessur la tranche à élément unique)
Adelmar


1

De nos jours, je préférerais toujours avoir cet assistant, comme suggéré dans une réponse php.net/end .

<?php
function endc($array) {
    return end($array);
}

$items = array('one','two','three');
$lastItem = endc($items); // three
$current = current($items); // one
?>

Cela gardera toujours le pointeur tel qu'il est et nous n'aurons jamais à nous soucier des parenthèses, des normes strictes ou quoi que ce soit.


Déjà mentionné ci-dessus: stackoverflow.com/a/45333947/1255289
miken32


-1

Et si vous voulez obtenir le dernier élément du tableau à l'intérieur de la boucle de son tableau?

Le code ci-dessous se traduira par une boucle infinie:

foreach ($array as $item) {
 $last_element = end($array);
 reset($array);
 if ($last_element == $item) {
   // something useful here
 }
}

La solution est évidemment simple pour les tableaux non associatifs:

$last_element = $array[sizeof ($array) - 1];
foreach ($array as $key => $item) {
 if ($last_element == $item) {
   // something useful here
 }
}

2
Je connais les fonctions end () et reset (). Mon commentaire était lié à des boucles comme foreach ou alors que vous ne pouvez pas utiliser ces fonctions car la fonction reset réinitialise le pointeur interne d'un tableau qui est utilisé dans la boucle pour l'itération. Désolé pour cela, la question était plus simple, je voulais juste donner une situation plus avancée que j'ai rencontrée dans mon projet. Meilleures salutations.
Vadim Podlevsky

C'est faux à bien des égards (tableaux avec doublons, comparaison non stricte ...) et en tout cas pas vraiment lié à la question.
Tgr

utilisez la fonction end ($ array) pour obtenir le dernier élément, pourquoi utilisez-vous inutilement des boucles?
Mahak Choudhary

1
@MahakChoudhary Mon commentaire est un ajout à "comment obtenir le dernier élément du tableau si vous effectuez déjà quelques manipulations à l'intérieur d'une boucle de ce tableau. L'utilisation de end () réinitialisera le pointeur innver et rompra la boucle d'itération.
Santé

-1
$file_name_dm =  $_FILES["video"]["name"];    

                           $ext_thumb = extension($file_name_dm);

                            echo extension($file_name_dm); 
function extension($str){
    $str=implode("",explode("\\",$str));
    $str=explode(".",$str);
    $str=strtolower(end($str));
     return $str;
}



En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.