Was ist der beste Weg, um das letzte Element eines Arrays zu erhalten, ohne es zu löschen?

427

OK,

Ich weiß alles über array_pop(), aber das löscht das letzte Element. Was ist der beste Weg, um das letzte Element eines Arrays zu erhalten, ohne es zu löschen?

EDIT: Hier ist ein Bonus:

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

oder auch

$array = array('a', 'b', 'c', 'd');
unset($array[2]);
echo $array[sizeof($array) - 1]; // Output: PHP Notice:  Undefined offset:  2 in - on line 4
Theodore R. Smith
quelle
11
Ob Sie es glauben oder nicht, ist es eine der schnellsten Methoden, mit denen ich dies verglichen habe. $ val = $ array [] = array_pop ($ array); echo $ val;
user2782001
2
Diese Frage führte zu vielen Optionen. Um mir bei der Auswahl zu helfen, habe ich einige der bemerkenswertesten / unterschiedlichen Optionen verglichen und die Ergebnisse als separate Antwort geteilt . (: @ user2782001 hat meinen Favoriten bisher im obigen Kommentar vorgeschlagen. :) Vielen Dank an alle für ihren Beitrag!
Paul van Leeuwen
1
@TheodoreRSmith Wenn PHP 7.3 veröffentlicht wird, können Sie in Betracht ziehen, diesen Vorschlag von Quasimodos Klon als "akzeptierte Antwort" zu betrachten (für Ihre Überlegung) ...
Paul van Leeuwen

Antworten:

175

Die vielen Antworten in diesem Thread bieten uns viele verschiedene Möglichkeiten. Um aus ihnen auswählen zu können, musste ich ihr Verhalten und ihre Leistung verstehen. In dieser Antwort werde ich meine Erkenntnisse mit Ihnen, gebenchmarkt gegen PHP - Versionen gemeinsam nutzen 5.6.38, 7.2.10und 7.3.0RC1( voraussichtlich 13. Dezember 2018 ).

Die Optionen, die <<option code>>ich testen werde, sind:

(Erwähnte Funktionen: array_key_last , array_keys , array_pop , array_slice , array_values , count , end , reset )

Die <<input code>>zu kombinierenden Testeingänge:

  • null =$array = null;
  • leer =$array = [];
  • last_null =$array = ["a","b","c",null];
  • auto_idx =$array = ["a","b","c","d"];
  • mischen =$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; }

Zum Testen ich das verwenden 5.6.38, 7.2.10und 7.3.0RC1 PHP Docker - Container wie:

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

Jede Kombination der oben aufgeführten <<option code>>s und <<input code>>s wird auf allen PHP-Versionen ausgeführt. Für jeden Testlauf wird das folgende Codefragment verwendet:

<<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);

Bei jedem Lauf wird var_dump den zuletzt abgerufenen letzten Wert der Testeingabe ausgeben und die durchschnittliche Dauer einer Iteration in Femtosekunden (0,000000000000001stel Sekunde) ausgeben .

Die Ergebnisse sind wie folgt:

/==========================================================================================================================================================================================================================================================================================================================================================================================================================\
||                                                                      ||                            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 ||
 \=========================================================================================================================================================================================================================================================================================================================================================================================================================/ 

Das oben erwähnte F Atal, W arnung und N Otice Codes übersetzen , wie:

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

Basierend auf dieser Ausgabe ziehe ich die folgenden Schlussfolgerungen:

  • Neuere Versionen von PHP bieten eine bessere Leistung mit Ausnahme dieser Optionen, die erheblich langsamer wurden:
    • Option .6. $x = end((array_values($array)));
    • Option .8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
  • Diese Optionen lassen sich am besten für sehr große Arrays skalieren:
    • 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)]; (seit PHP 7.3)
  • Diese Optionen sollten nur für automatisch indizierte Arrays verwendet werden :
    • Option .7. $x = $array[count($array)-1];(aufgrund der Verwendung voncount)
    • Option .9. $x = $array[] = array_pop($array);(aufgrund der Zuweisung von Wertverlust des Originalschlüssels)
  • Diese Option behält den internen Zeiger des Arrays nicht bei
    • Option .5. $x = end($array); reset($array);
  • Diese Option ist ein Versuch, Option .5 zu ändern . um den internen Zeiger des Arrays zu erhalten (aber leider lässt er sich für sehr große Arrays nicht gut skalieren)
    • Option .6. $x = end((array_values($array)));
  • Die neue array_key_lastFunktion scheint keine der oben genannten Einschränkungen zu haben, mit der Ausnahme, dass sie zum Zeitpunkt des Schreibens noch ein RC ist (verwenden Sie also den RC oder warten Sie auf die Veröffentlichung im Dezember 2018):
    • Option 10. $x = $array[array_key_last($array)]; (seit PHP 7.3)

Je nachdem, ob Sie das Array als Stapel oder als Warteschlange verwenden , können Sie Option 9 variieren .

Paul van Leeuwen
quelle
Wenn Sie feststellen, dass eine bestimmte Option fehlt, können Sie sie selbst testen, indem Sie die obigen Codefragmente kopieren und mit einer zuvor getesteten Option vergleichen. Wenn Sie dieser Liste eine Option hinzufügen, werden alle Kombinationen erneut auf vergleichbare Leistungsergebnisse getestet. Wenn Sie eine bestimmte Option haben, die Ihrer Meinung nach hinzugefügt werden sollte, hinterlassen Sie bitte einen Kommentar. Ich beabsichtige, ihn dann hinzuzufügen (obwohl dies einige Zeit dauern kann).
Paul van Leeuwen
1
Sehr gute Antwort, ein Kommentar: Für assoziative Arrays kann Option 9 nicht ebenfalls verwendet werden, da wir anstelle des vorherigen Schlüsselnamens einen automatisch indizierten Schlüssel zurückweisen.
Gras Double
1
Schöne Zusammenfassung! Bitte fügen Sie meine Antwort mit dem neuen PHP 7.3 hinzu. Funktion $array[array_key_last($array)];zu Ihrem Benchmark. Und bitte benachrichtigen Sie mich, wenn Sie fertig sind. Ich möchte die Leistungsergebnisse im Vergleich sehen.
Quasimodos Klon
2
@sz Es wurde hauptsächlich mit viel Sturheit und Geduld produziert, aber die allgemeine Auswahl und die mehrzeiligen Bearbeitungsfunktionen des Sublime-Texteditors halfen. Die Regeneration dauerte fast einen Tag. Wenn ich es also noch einmal machen muss, werde ich wahrscheinlich etwas schreiben, das die Ausgabe aller 210 Docker-Ausführungen automatisch in eine Tabelle konvertiert :-)
Paul van Leeuwen
1
@ quasimodos-clone Ich habe die gesamte Tabelle basierend auf den neuesten PHP 5, 7 und Ihrem RC neu generiert. Ich nehme an, wir werden es im Dezember wieder generieren wollen, wenn es tatsächlich veröffentlicht wird. Vielen Dank, dass Sie alle auf diese neue Funktion aufmerksam gemacht haben.
Paul van Leeuwen
487

Versuchen

$myLastElement = end($yourArray);

So setzen Sie es zurück (danke @hopeseekr):

 reset($yourArray);

Link zum Handbuch

@ David Murdoch fügte hinzu: $myLastElement = end(array_values($yourArray));// and now you don't need to call reset(). Auf E_STRICT wird die Warnung ausgegeben

Strict Standards: Only variables should be passed by reference

Danke o_O Tync und allen!

Iznogood
quelle
38
Verwenden Sie $myLastElement = end(array_values($yourArray));und jetzt müssen Sie nicht mehr anrufen reset().
David Murdoch
5
@ DavidMurdoch Vielleicht, aber es verschiebt sicher den RAM und die CPU und erstellt das temporäre Array für die Array-Werte ...
Theodore R. Smith
12
Wenn Ihr Server zu viel RAM verbraucht, sodass das Aufrufen einer einfachen Zusatzfunktion einen Deal Breaker darstellt, empfehlen wir Ihnen, die Konfiguration und die Ressourcen Ihres Servers erneut zu überprüfen.
Chris Baker
3
end(array_values())wird ein E_STRICT geben: "Nur Variablen sollten als Referenz übergeben werden"
kolypto
32
Fügen Sie zusätzliche Klammern hinzu, um die strenge Warnung zu vermeiden:end((array_values($yourArray)))
Daniel W.
212

Kurz und bündig.

Ich habe eine Lösung gefunden, um Fehlermeldungen zu entfernen und die Einzeilerform und die effiziente Leistung beizubehalten:

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

- vorherige Lösung

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

Hinweis: Die zusätzlichen Klammern werden benötigt, um a zu vermeiden PHP Strict standards: Only variables should be passed by reference.

Rolacja
quelle
31
Nach genau 5 Jahren, 6 Monaten und 2 Tagen haben Sie eine überlegenere Antwort abgegeben !! Vielen Dank! und danke Stack Overflow !!
Theodore R. Smith
1
Grüße die Antwort, aber das Hinzufügen der zusätzlichen Klammern fühlt sich ein wenig hackisch an. Auch phpStorm markiert dies als Fehler. Zusätzliche Informationen zum Hinzufügen zusätzlicher Klammern ( phpsadness.com/sad/51 ). Um den Fehler zu überwinden, könnten Sie dies zu einem '2-Liner' machen: $array = array_slice($array, -1); $lastEl = array_pop($array);Persönlich denke ich, dass dies besser ist (ohne den Parser 'Bug')
Maurice
3
Sie können die Dereferenzierung wie folgt verwenden: array_slice ($ array, -1) [0]
Vikash
1
Sie können nicht, wenn Sie Zeichenfolgen als Index im Array haben
Rolacja
3
Diese Antwort erfordert noch mindestens zwei Überprüfungen, um PHP-Benachrichtigungen zu vermeiden. 1. Überprüfen Sie, ob das array_size() > 1 2. Überprüfen Sie, ob das Array tatsächlich ein Array ist. Ich halte mich immer noch an die Antwort von @Iznogood, da die in PHP integrierte end()Funktion bereits die ganze harte Arbeit effizienter erledigt.
Ema4rl
37

Was ist los mit array_slice($array, -1)? (Siehe Handbuch: http://us1.php.net/array_slice )

array_slice()gibt ein Array zurück. Wahrscheinlich nicht das, wonach Sie suchen. Sie wollen das Element.

Stoutie
quelle
21
Verwenden Sie array_slice($array, -1)[0], um das Element zu erhalten.
Pang
2
Das ist die Antwort. "end" Den internen Zeiger des Arrays ändern? Nach Ärger fragen und sehr schwer zu lesen!
Gerard ONeill
Ich liebe diesen Ansatz, obwohl er, wie @Pang betont, nicht ganz vollständig ist. reset(array_slice($array, -1))ist ein anderer Ansatz (der keinen Fehler verursacht, wenn array_slice()etwas "kleineres" als ein Einzelelement-Array zurückgegeben wird)
Rinogo
Der beste Ansatz, da Sie das Element direkt ändern können:array_slice($array, -1)[0] = "";
HAlex
20

Eine Möglichkeit, Referenzfehler zu vermeiden (z. B. "end (array_values ​​($ foo))"), ist die Verwendung von call_user_func oder 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))));
Warbo
quelle
Toller Ansatz! (Geben Sie hier den Standard 'Dies sollte die akzeptierte Antwort sein' ein)
Tippfehler
3
Oder fügen Sie einfach eine zusätzliche Paranthesis hinzu. Kürzer und süßer:end((array_values($yourArray)))
Dzhuneyt
4
Der zusätzliche Klammertrick beruht auf einem Fehler in PHP, und dieser Ansatz funktioniert in späteren Versionen von PHP (oder zumindest nicht in PHP 7) nicht mehr.
Matt Browne
1
Und der call_user_funcTrick funktioniert auch in PHP 7 nicht. Ich denke, Sie müssen keine temporäre Variable erstellen.
Matt Browne
15

Wenn Sie den internen Zeiger nicht ändern möchten (unterstützt sowohl indizierte als auch assoziative Arrays):

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

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


Wenn Sie eine Dienstprogrammfunktion wünschen, die den internen Zeiger nicht ändert (da das Array als Wert übergeben wird und die Funktion eine Kopie davon bearbeitet):

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

Beachten Sie, dass PHP Kopien "on-the-fly" erstellt, dh nur, wenn sie tatsächlich benötigt werden. Das end()selbst ändert das Array, sodass intern eine Kopie des Arrays generiert wird.


Daher ist die folgende Alternative tatsächlich schneller, da das Array intern nicht kopiert wird, sondern nur ein Slice erstellt wird:

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

Dieses "foreach / return" ist eine Optimierung, um das erste (und hier einzelne) Element effizient zu erhalten.


Endlich die schnellste Alternative, aber nur für indizierte Arrays:

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



Für die Aufzeichnung ist hier eine andere Antwort von mir , für das erste Element des Arrays.

Gras Double
quelle
Sie bieten 2 alternative Implementierungen für eine array_lastFunktion. Zum einen geben Sie an, dass das $arraykopiert wird und zum anderen, dass es nicht kopiert wird. Wo ist der Unterschied / warum wird er in der ersten Implementierung und nicht in der zweiten kopiert?
Paul van Leeuwen
1
@ PaulvanLeeuwen Ich habe verstanden, warum Sie verwirrt wurden. Ich habe versucht, die Antwort zu klären , ist es besser?
Gras Double
10

ungetestet: würde das nicht funktionieren?

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

Da das von array_values ​​zurückgegebene Array flüchtig ist, kümmert es niemanden, ob sein Zeiger zurückgesetzt wird.

und wenn Sie den Schlüssel dazu brauchen, würden Sie wahrscheinlich tun:

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

Ich brauche das ziemlich oft, um mit Stacks fertig zu werden, und ich bin immer verblüfft, dass es keine native Funktion gibt, die dies tut, ohne das Array oder seinen internen Zeiger in irgendeiner Form zu manipulieren.

Daher trage ich normalerweise eine util-Funktion mit mir herum, die auch auf assoziativen Arrays sicher verwendet werden kann.

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

    $keys = array_keys($array);
    return $array[$keys[sizeof($keys) - 1]];
}
thrau
quelle
1
Gute Nachrichten, sie machen es zu einer nativen Funktion :-) Sie können die Release-Planung hier im Auge behalten: wiki.php.net/todo/php73 (voraussichtlich 13. Dezember 2018 zum Zeitpunkt dieses Schreibens).
Paul van Leeuwen
9

Verwenden Sie Folgendes, um das letzte Element eines Arrays abzurufen:

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

Benchmark

Ich habe 1.000 Mal iteriert und das letzte Element kleiner und großer Arrays mit 100 bzw. 50.000 Elementen erfasst.

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

Ich habe PHP Version 5.5.32 verwendet.

Westy92
quelle
Was ist mit $ array [array_keys ($ array) [count (array_keys ($ array)) - 1]]?
user2782001
hmm..array_keys scheint ziemlich schlecht zu skalieren.
user2782001
1
Es ist tatsächlich schneller verrückt, wenn das große Array (0,0002) das Element öffnet und wieder auflegt ... $ val = $ ar [] = $ array_pop ($ ar);
user2782001
1
@ Westy92 Ihre Einheiten scheinen im Benchmark falsch zu sein. Die kleinste Zahl, die Sie angeben, ist 0,00031 ... Mikrosekunden, was ungefähr 0,3 Nanosekunden entspricht. Das würde bedeuten, dass Ihr Test einen Takt benötigt, um ausgeführt zu werden, wenn Sie einen neuen Computer haben. Ich vermute, Sie meinten entweder Millisekunden oder möglicherweise sogar Sekunden .
Cesoid
1
Die Werte sind eindeutig mehrere Größenordnungen falsch. Warum überhaupt der Fokus auf Leistung?
Istepaniuk
6

end () liefert das letzte Element eines Arrays

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

$array1 = array('a', 'b', 'c', 'd');
echo end($array1); //output: d
Ajith
quelle
1
Diese Lösung funktioniert, aber sie ändert den internen Zeiger des Arrays. Ich denke nicht, dass dies der richtige Weg ist.
UnixAgain
5

Ab PHP Version 7.3 wurden die Funktionen array_key_firstund array_key_lasteingeführt.

Da Arrays in PHP keine strengen Array-Typen sind, dh Sammlungen von Feldern mit fester Größe ab Index 0, sondern dynamisch erweiterte assoziative Arrays, ist die Behandlung von Positionen mit unbekannten Schlüsseln schwierig und Problemumgehungen funktionieren nicht sehr gut. Im Gegensatz dazu würden reale Arrays sehr schnell intern über Zeigerarithmethik adressiert, und der letzte Index ist bereits zur Kompilierungszeit durch Deklaration bekannt.

Zumindest das Problem mit der ersten und letzten Position wird jetzt seit Version 7.3 durch eingebaute Funktionen gelöst. Dies funktioniert sogar ohne Warnungen bei sofort einsatzbereiten Array-Literalen :

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

Offensichtlich ist der letzte Wert :

$array[array_key_last($array)];
Quasimodos Klon
quelle
1
Vielen Dank, dass Sie alle darauf aufmerksam gemacht haben. Für diejenigen, die dies gerne nutzen: Bitte nicht, dass dies zum Zeitpunkt dieses Schreibens ein RC ist. Es ist für die Veröffentlichung im Dezember 2018 geplant.
Paul van Leeuwen
1
Das sind gute Nachrichten. Ich habe gerade eine Polyfill / Shim in meiner Antwort unten gepostet, damit die Leute diese Syntax sofort verwenden können.
Mark Thomson
3
$lastValue = end(array_values($array))

$ Array-Zeiger werden nicht geändert. Dies vermeidet das

reset($array)

was unter bestimmten Bedingungen möglicherweise nicht erwünscht ist.

Vihaan Verma
quelle
3

Für mich:

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

Mit Mitarbeitern:

$last =array_values($array)[count($array - 1)]
Mirko Pagliai
quelle
Bitte geben Sie einen Kontext für Ihre Antwort an.
Shawn
2
@Shawn Welcher Kontext? Ich brauche keinen Kontext. Code für assoziative Arrays hinzugefügt.
Mirko Pagliai
3

Die besten Antworten sind großartig, aber wie von @ paul-van-leeuwen und @ quasimodos-clone erwähnt, wird PHP 7.3 zwei neue Funktionen einführen, um dieses Problem direkt zu lösen - array_key_first () und array_key_last () .

Sie können diese Syntax heute mit den folgenden Polyfill- (oder Shim-) Funktionen verwenden.

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

Vorsichtsmaßnahme: Dies erfordert PHP 5.4 oder höher.

Mark Thomson
quelle
2

Um dies zu tun und das E_STRICT zu vermeiden und nicht mit dem internen Zeiger des Arrays herumzuspielen, können Sie Folgendes verwenden:

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

$last_element = lelement($array);

lelement funktioniert nur mit einer Kopie, sodass der Zeiger des Arrays nicht beeinflusst wird.

Damiene
quelle
2

Eine andere Lösung:

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

Noch eine mögliche Lösung ...

$last_element = array_reverse( $array )[0];
Charles Garrison
quelle
Nicht an assoziativen Arrays zu arbeiten, scheint mir kein Grund genug zu sein, mich abzulehnen. In Bezug auf die Qualität ist diese Antwort nicht schlechter als viele andere Antworten auf diese Frage. Ich verstehe nicht, warum ich zu diesem Zeitpunkt mindestens 2 Abstimmungen sehe. (Punktzahl von -2). Wie auch immer, positiv für mich, es ist nicht so schlimm.
Paul van Leeuwen
2

Wie wäre es mit:

current(array_slice($array, -1))
  • funktioniert für assoziative Arrays
  • funktioniert wenn $array == [](zurück false)
  • wirkt sich nicht auf das ursprüngliche Array aus
Bouke Versteegh
quelle
2

Sie erhalten das letzte Element einfach aus einem Array, indem Sie die folgende Logik verwenden

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

Nicht nur das letzte Element, sondern Sie können auch das vorletzte, drittletzte usw. erhalten, indem Sie die folgende Logik verwenden.

Für das vorletzte Element müssen Sie in der obigen Anweisung nur die Nummer 2 übergeben, zum Beispiel:
echo ($ array [count ($ array) -2]);

Amzad Khan
quelle
1

So erhalten Sie den letzten Wert von Array:

array_slice($arr,-1,1) ;

Zum Entfernen des Formulararrays für den letzten Wert:

array_slice($arr,0,count($arr)-1) ;
Rishabh
quelle
1
array_slice($arr,-1,1)wird zu einem anderen Array mit der Länge 1 führen, nicht das letzte Element
Vic
Nehmen wir ein Beispiel: $a=array("red","green","blue","yellow","brown"); print_r(array_slice($a,-1,1)); Ergebnis:Array ( [0] => brown )
Rishabh
1

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

Setzt das Array nicht zurück und gibt keine STRICT-Warnungen aus.

PS. Da die am häufigsten gewählte Antwort immer noch nicht die doppelte Klammer enthält, habe ich diese Antwort eingereicht.

Daan
quelle
1

Ich denke, dies ist eine leichte Verbesserung gegenüber allen vorhandenen Antworten:

$lastElement = count($array) > 0 ? array_values(array_slice($array, -1))[0] : null;
  • Funktioniert besser als end()oder mit Lösungen array_keys(), insbesondere bei großen Arrays
  • Der interne Zeiger des Arrays wird nicht geändert
  • Es wird nicht versucht, auf einen undefinierten Offset für leere Arrays zuzugreifen
  • Funktioniert wie erwartet für leere Arrays, indizierte Arrays, gemischte Arrays und assoziative Arrays
Adelmar
quelle
Leider funktioniert es nicht mit assoziativen Arrays, da das einzelne Element des Slice möglicherweise einen benannten Schlüssel hat.
Gras Double
Sie haben Recht, bearbeitet, um einen Fix hinzuzufügen ( array_valuesauf dem Einzelelement-Slice)
Adelmar
1

Verwenden Sie die Funktion end ().

$array = [1,2,3,4,5];
$last = end($array); // 5
Brian Berneker
quelle
1
Achten Sie einfach darauf, dass diese Funktion den Zeiger Ihres Arrays auf diese Position bewegt.
Giovannipds
Beachten Sie auch, dass dies 8 Jahre zuvor als Antwort veröffentlicht wurde. stackoverflow.com/a/3687368/1255289
miken32
1

Heutzutage würde ich es vorziehen, immer diesen Helfer zu haben, wie in einer Antwort von php.net/end vorgeschlagen .

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

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

Dadurch bleibt der Zeiger immer unverändert, und wir müssen uns nie um Klammern, strenge Standards oder was auch immer kümmern.

Giovannipds
quelle
Bereits oben erwähnt: stackoverflow.com/a/45333947/1255289
miken32
0

Hinweis: Für (PHP 7> = 7.3.0) können wir array_key_last verwenden - Ruft den letzten Schlüssel eines Arrays ab

array_key_last ( array $array ) : mixed

Ref: http://php.net/manual/en/function.array-key-last.php

lokender singh
quelle
1
Dies wurde bereits in mehreren anderen Antworten behandelt.
Miken32
aber ich antwortete früher als andere
lokender singh
-1

Was ist, wenn Sie das letzte Element des Arrays innerhalb der Schleife des Arrays erhalten möchten?

Der folgende Code führt zu einer Endlosschleife:

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

Die Lösung ist für nicht assoziative Arrays offensichtlich einfach:

$last_element = $array[sizeof ($array) - 1];
foreach ($array as $key => $item) {
 if ($last_element == $item) {
   // something useful here
 }
}
Vadim Podlevsky
quelle
2
Ich kenne die Funktionen end () und reset (). Mein Kommentar bezog sich auf Schleifen wie foreach oder while, bei denen Sie diese Funktionen nicht verwenden können, da die Reset-Funktion den inneren Zeiger eines Arrays zurücksetzt, das in der Schleife für die Iteration verwendet wird. Entschuldigung, die Frage war einfacher, ich wollte nur eine fortgeschrittenere Situation angeben, auf die ich in meinem Projekt gestoßen bin. Freundliche Grüße.
Vadim Podlevsky
Dies ist in vielerlei Hinsicht falsch (Arrays mit Duplikaten, nicht strenger Vergleich ...) und auf jeden Fall nicht wirklich mit der Frage verbunden.
Tgr
Verwenden Sie die Funktion end ($ array), um das letzte Element abzurufen. Warum verwenden Sie unnötigerweise Schleifen?
Mahak Choudhary
1
@MahakChoudhary Mein Kommentar ist eine Ergänzung zu "Wie man das letzte Element des Arrays erhält, wenn man einige Manipulationen bereits in einer Schleife dieses Arrays vornimmt. Mit end () wird der Innver-Zeiger zurückgesetzt und die Iterationsschleife unterbrochen. Prost!
Vadim Podlevsky
-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;
}
Hussy Borad
quelle
-1

Ab PHP 7.3 array_key_lastist verfügbar

$lastEl = $myArray[array_key_last($myArray)];
Tagarikdi Djakouba
quelle
Dies wurde bereits in mehreren anderen Antworten erwähnt.
Miken32
-1

Sehr einfach

$array = array('a', 'b', 'c', 'd');
end($array)
Jasmeen Maradeeya
quelle
Es ist zu erwähnen, dass dies ein seltsames Verhalten aufweist, wenn Sie Arrays mit Lücken verwenden. dh $a = array(); $a[2] = 'c'; $a[1] = 'b'; echo end($a); wird zurückkehrenb
Simon Zyx
Dies wurde bereits vor 9 Jahren gepostet. stackoverflow.com/a/3687368/1255289
miken32