556 Stimmen

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

Gut,

Ich weiß alles über array_pop() , aber damit wird das letzte Element gelöscht. 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 sogar

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

13 Stimmen

Ob Sie es glauben oder nicht, das Aufbrechen und Wiederaufsetzen ist eine der schnellsten Methoden, die ich in einem Benchmarking ermittelt habe. $val=$array[]=array_pop($array); echo $val;

2 Stimmen

Bei dieser Frage gab es viele Möglichkeiten. Um mir bei der Auswahl zu helfen, habe ich die bemerkenswertesten/unterscheidbarsten Optionen verglichen und die Ergebnisse geteilt als separate Antwort . (:@user2782001 schlug meinen bisherigen Favoriten im obigen Kommentar vor:) Vielen Dank an alle, die dazu beigetragen haben!

2 Stimmen

@TheodoreRSmith Wenn PHP 7.3 veröffentlicht wird, könnten Sie in Erwägung ziehen, die ( dieser VorschlagQuasimodos Klon die "akzeptierte Antwort" (zu Ihrer Information)...

616voto

Iznogood Punkte 11839

Versuchen Sie

$myLastElement = end($yourArray);

Link zu Handbuch .

Oder eine Lösung mit PHP >= 7.3.0:

(Was im Gegensatz zu end(...) , ändert den internen Iterator nicht).

$myLastElement = $yourArray[array_key_last($yourArray)];

Link zu Handbuch

1 Stimmen

Fantastisch! Natürlich weiß ich über das Handbuch (wie ich es in meiner Frage verlinkt), aber es ist eine Menge von Funktionen zu analysieren und ich vermisste, dass man. Danke, Bruder.

0 Stimmen

@hopeseekr Ich habe das Handbuch verlinkt, damit Sie den Eintrag für end() lesen können, nicht weil ich Ihnen beigebracht habe, dass Sie es nicht kennen :) Und es hilft anderen, die hier nach der gleichen Frage suchen werden. Ich freue mich, geholfen zu haben!

2 Stimmen

Das Problem mit end($array) ist, dass es den internen Zeiger des Arrays ändert, um auf das letzte Element zu zeigen, was ein Problem sein könnte, abhängig von Ihren Implementierungsdetails.

352voto

Paul van Leeuwen Punkte 3730

Die vielen Antworten in diesem Thread bieten uns viele verschiedene Möglichkeiten. Um eine Auswahl treffen zu können, musste ich ihr Verhalten und ihre Leistung verstehen. In dieser Antwort werde ich meine Ergebnisse mit Ihnen teilen, die ich mit PHP-Versionen verglichen habe 5.6.38 , 7.2.10 y 7.3.0RC1 ( voraussichtlich 13. Dezember 2018 ).

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

(genannte Funktionen: array_key_last , array_keys , array_pop , array_slice , array_values , zählen , Ende , zurücksetzen )

Die Testeingänge ( <<input code>> s) zu kombinieren:

  • null \= $array = null;
  • leer \= $array = [];
  • letzte_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 werde ich die 5.6.38 , 7.2.10 y 7.3.0RC1 PHP-Docker-Container mögen:

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

Jede Kombination der oben genannten <<option code>> s und <<input code>> s werden auf allen PHP-Versionen ausgeführt. Für jeden Testlauf wird der folgende Codeschnipsel 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);

Für jeden Durchlauf wird var_dump den zuletzt abgerufenen letzten Wert der Testeingabe ausgeben und die durchschnittliche Dauer einer Iteration drucken in Femtosekunden (0,000000000000001stel einer Sekunde).

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

Die oben genannten F atal, W arning und N otice Codes übersetzen als:

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

Auf der Grundlage dieser Ergebnisse ziehe ich die folgenden Schlussfolgerungen:

  • Neuere PHP-Versionen sind besser, mit Ausnahme dieser Optionen, die deutlich langsamer geworden sind:
    • Option .6. $x = end((array_values($array)));
    • Option .8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
  • Diese Optionen sind am besten für sehr große Arrays geeignet:
    • 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 selbstindizierte Arrays verwendet werden :
    • Option .7. $x = $array[count($array)-1]; (aufgrund der Verwendung von count )
    • Option .9. $x = $array[] = array_pop($array); (aufgrund der Zuweisung eines Wertes, der den ursprünglichen Schlüssel verliert)
  • diese Option behält den internen Zeiger des Arrays nicht bei
    • Option .5. $x = end($array); reset($array);
  • diese Option ist ein Versuch, die Option .5. um den internen Zeiger des Arrays zu erhalten (aber leider ist dies für sehr große Arrays nicht gut skalierbar)
    • Option .6. $x = end((array_values($array)));
  • die neue array_key_last Funktion scheint keine der oben genannten Einschränkungen zu haben, mit der Ausnahme, dass es sich zum Zeitpunkt dieses Schreibens noch um einen RC handelt (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)

Ein bisschen, je nachdem, ob Verwendung des Arrays als Stapel oder als Warteschlange können Sie Variationen zu Option 9 erstellen.

0 Stimmen

Wenn Sie feststellen, dass eine bestimmte Option fehlt, können Sie sie selbst testen, indem Sie die obigen Codeschnipsel zusammenkopieren und mit einer zuvor getesteten Option vergleichen. Das Hinzufügen einer Option zu dieser Liste würde bedeuten, dass alle Kombinationen erneut auf vergleichbare Leistungsergebnisse getestet werden. Wenn Sie eine bestimmte Option haben, die Ihrer Meinung nach hinzugefügt werden sollte, schreiben Sie bitte einen Kommentar, ich werde sie dann hinzufügen (auch wenn es einige Zeit dauern kann).

1 Stimmen

Sehr gute Antwort, eine Bemerkung aber: für assoziative Arrays Option 9 kann nicht verwendet werden, weil wir zurück zu einem automatisch indizierten Schlüssel anstelle des vorherigen Schlüsselnamen zuweisen.

0 Stimmen

@GrasDouble Danke, und verdammt, du hast recht. Ich habe PHP nicht viel benutzt, nachdem ich diese Antwort geschrieben habe :-$. Haben wir (mutmaßlich) leistungsfähige Optionen für große assoziative Arrays?

218voto

rolacja Punkte 2333

Kurz und knapp.

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

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

-- bisherige Lösung

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

Hinweis: Die zusätzlichen Klammern sind erforderlich, um eine PHP Strict standards: Only variables should be passed by reference .

33 Stimmen

Nach genau 5 Jahren, 6 Monaten und 2 Tagen haben Sie eine bessere Antwort eingereicht!! Danke! und danke Stack Overflow!!

1 Stimmen

Gute Antwort, aber die zusätzlichen Klammern wirken ein wenig hakelig. Außerdem wird phpStorm dies als Fehler markieren. Extra Info für das Hinzufügen zusätzlicher Klammern ( phpsadness.com/sad/51 ). Um den Fehler zu beheben, könnten Sie daraus einen "2-Zeiler" machen: $array = array_slice($array, -1); $lastEl = array_pop($array); Ich persönlich denke, dass dies besser ist (ohne den Parser "Bug")

0 Stimmen

Sie können es auch als Einzeiler und ohne zusätzliche Variable erhalten: $lastEl = array_pop($lastEl = (array_slice($array, -1)));

45voto

Stoutie Punkte 1804

Was ist falsch an 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.

30 Stimmen

使用する array_slice($array, -1)[0] um das Element zu erhalten.

3 Stimmen

Das ist die Antwort. "end" Ändern Sie den internen Zeiger des Arrays? Ärgerlich und sehr schwer zu lesen!

0 Stimmen

Dieser Ansatz gefällt mir, auch wenn er, wie @Pang anmerkt, nicht ganz vollständig ist. reset(array_slice($array, -1)) ist ein weiterer Ansatz (der keinen Fehler verursacht, wenn array_slice() gibt alles zurück, was "kleiner" als ein Einzelelement-Array ist)

22voto

Gras Double Punkte 14944

Wenn Sie sich nicht darum kümmern, den internen Zeiger zu ändern (die folgenden Zeilen unterstützen 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 Utility-Funktion wollen, die den internen Zeiger nicht verändert (weil das Array als Wert an die Funktion übergeben wird, so dass die Funktion mit einer Kopie davon arbeitet):

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

PHP erstellt jedoch Kopien "on-the-fly", d.h. nur bei tatsächlichem Bedarf. Da die end() Funktion das Array verändert, wird intern eine Kopie des gesamten Arrays (minus ein Element) erzeugt.

Daher würde ich die folgende Alternative empfehlen, die tatsächlich schneller ist, da sie intern das Array nicht kopiert, sondern nur ein Slice erstellt:

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

Darüber hinaus ist das "foreach / return" eine Optimierung, um effizient das erste (und hier einzige) Element zu erhalten.

Schließlich die schnellste Alternative, aber nur für indizierte Arrays (und ohne Lücken):

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

Für das Protokoll, hier ist eine weitere Antwort von mir für das erste Element des Arrays.

0 Stimmen

Sie bieten 2 alternative Implementierungen für eine array_last Funktion. Für die erste geben Sie an, dass die $array kopiert wird und für die zweite, dass sie nicht kopiert wird. Wo liegt der Unterschied / warum wird er bei der ersten Implementierung kopiert und bei der zweiten nicht?

1 Stimmen

@PaulvanLeeuwen Ich habe verstanden, warum Sie verwirrt waren. Ich habe versucht die Antwort klären ist es besser?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X