Jaki jest najlepszy sposób na uzyskanie ostatniego elementu tablicy bez usuwania go?

427

Ok,

Wiem wszystko array_pop(), ale to usuwa ostatni element. Jaki jest najlepszy sposób na uzyskanie ostatniego elementu tablicy bez usuwania go?

EDYCJA: Oto bonus:

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

lub nawet

$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
źródło
11
Uwierz lub nie wskakuj i włóż to z powrotem, to jeden z najszybszych sposobów, w jaki przeprowadziłem testy porównawcze. $ val = $ array [] = array_pop ($ array); echo $ val;
user2782001
2
To pytanie spowodowało wiele opcji. Aby pomóc sobie dokonać wyboru, dokonałem porównania najbardziej znaczących / odrębnych opcji i podzieliłem się wynikami jako osobną odpowiedź . (: @ user2782001 zasugerował mój ulubiony do tej pory w powyższym komentarzu. :) Dziękujemy wszystkim za wkład!
Paul van Leeuwen,
1
@TheodoreRSmith Kiedy PHP 7.3 jest zwolniony można rozważyć ( ta sugestia o klonie Quasimodo jest do „odpowiedzi zaakceptowane” (za uwagę) ...
Paul van Leeuwen

Odpowiedzi:

175

Wiele odpowiedzi w tym wątku przedstawia nam wiele różnych opcji. Aby móc z nich wybierać, musiałem zrozumieć ich zachowanie i wydajność. W tej odpowiedzi będę dzielić się z wami moimi odkryciami, na podstawie porównania z wersjami PHP 5.6.38, 7.2.10i 7.3.0RC1( oczekiwano 13 grudnia 2018 ).

Opcje <<option code>>, które przetestuję, to:

(wspomniane funkcje: array_key_last , array_keys , array_pop , array_slice , array_values , count , end , reset )

Wejścia testowe <<input code>>do połączenia z:

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

Do testowania będę używać 5.6.38, 7.2.10i 7.3.0RC1 PHP pojemniki dokowane jak:

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

Każda kombinacja wyżej wymienionych <<option code>>s i <<input code>>s będzie działać na wszystkich wersjach PHP. Do każdego uruchomienia testowego używany jest następujący fragment kodu:

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

Dla każdego przebiegu spowoduje to var_dump ostatnio pobraną ostatnią wartość wejścia testowego i wydrukowanie średniego czasu trwania jednej iteracji w femtosekundach (0,000000000000001 000 sekundy).

Wyniki są następujące:

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

Wyżej wymienione kody F atal, W arning i N otice tłumaczą się następująco:

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

Na podstawie tych wyników wyciągam następujące wnioski:

  • nowsze wersje PHP działają lepiej, z wyjątkiem tych opcji, które stały się znacznie wolniejsze:
    • opcja .6. $x = end((array_values($array)));
    • opcja .8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
  • opcje te najlepiej skalują się dla bardzo dużych tablic:
    • opcja .5. $x = end($array); reset($array);
    • opcja .7. $x = $array[count($array)-1];
    • opcja .9. $x = $array[] = array_pop($array);
    • opcja 10. $x = $array[array_key_last($array)]; (od PHP 7.3)
  • opcji tych należy używać tylko w przypadku tablic z autoindeksowaniem :
    • opcja .7. $x = $array[count($array)-1];(z powodu użyciacount)
    • opcja .9. $x = $array[] = array_pop($array);(z powodu przypisania utraconego klucza oryginalnego)
  • ta opcja nie zachowuje wewnętrznego wskaźnika tablicy
    • opcja .5. $x = end($array); reset($array);
  • ta opcja jest próbą modyfikacji opcji .5. aby zachować wewnętrzny wskaźnik tablicy (ale niestety nie skaluje się dobrze dla bardzo dużych tablic)
    • opcja .6. $x = end((array_values($array)));
  • array_key_lastwydaje się, że nowa funkcja nie ma żadnego z wyżej wymienionych ograniczeń, z wyjątkiem tego, że w chwili pisania tego tekstu nadal jest RC (więc użyj RC lub poczekaj na wydanie Gru 2018):
    • opcja 10. $x = $array[array_key_last($array)]; (od PHP 7.3)

Nieco w zależności od tego, czy używasz tablicy jako stosu, czy jako kolejki , możesz wprowadzać zmiany w opcji 9.

Paul van Leeuwen
źródło
Jeśli zauważysz brak konkretnej opcji, możesz ją przetestować samodzielnie, kopiując i wklejając powyższe fragmenty kodu, porównując ją z poprzednio przetestowaną opcją. Aby dodać opcję do tej listy, należy ponownie przetestować wszystkie kombinacje w celu uzyskania porównywalnych wyników. Jeśli masz konkretną opcję, która Twoim zdaniem powinna zostać dodana, zostaw komentarz, zamierzam go następnie dodać (choć może to trochę potrwać).
Paul van Leeuwen,
1
Bardzo dobra odpowiedź, jeden komentarz: w przypadku tablic asocjacyjnych nie można również użyć opcji 9, ponieważ zamiast poprzedniej nazwy klucza przypisujemy z powrotem do klucza automatycznie indeksowanego.
Gras Double
1
Ładne podsumowanie! Proszę dodać moją odpowiedź, używając nowego PHP 7.3. funkcja $array[array_key_last($array)];do twojego testu porównawczego. Po zakończeniu proszę o powiadomienie. Chciałbym zobaczyć wyniki wydajności w porównaniu.
Klon Quasimodo
2
@sz został wyprodukowany głównie z dużą upartością i cierpliwością, ale pomogła ogólna selekcja i wieloliniowe funkcje edytora Sublime. regeneracja zajęła prawie dzień, więc jeśli będę musiał to zrobić ponownie, prawdopodobnie napiszę coś, co automatycznie konwertuje dane wyjściowe wszystkich 210 wykonań dokerów do tabeli :-)
Paul van Leeuwen,
1
@ quasimodos-clone Zregenerowałem całą tabelę na podstawie najnowszej wersji PHP 5, 7 i twojego RC. Przypuszczam, że będziemy chcieli go wygenerować ponownie w grudniu, kiedy zostanie faktycznie wydany. Dziękujemy za zwrócenie uwagi na tę nową funkcję.
Paul van Leeuwen
487

Próbować

$myLastElement = end($yourArray);

Aby go zresetować (dzięki @hopeseekr):

 reset($yourArray);

Link do instrukcji

@David Murdoch dodał: $myLastElement = end(array_values($yourArray));// and now you don't need to call reset(). Na E_STRICT generuje to ostrzeżenie

Strict Standards: Only variables should be passed by reference

Dzięki o_O Tync i wszystkim!

Iznogood
źródło
38
Użyj, $myLastElement = end(array_values($yourArray));a teraz nie musisz dzwonić reset().
David Murdoch,
5
@DavidMurdoch Być może, ale z pewnością powoduje ubijanie pamięci RAM i procesora, tworząc tablicę temp dla wartości tablic ...
Theodore R. Smith
12
Jeśli Twój serwer zużywa zbyt dużo pamięci RAM, więc wywołanie jednej prostej dodatkowej funkcji stanowi przeszkodę, sugeruję ponowne sprawdzenie konfiguracji i zasobów serwera.
Chris Baker,
3
end(array_values())da E_STRICT: „Tylko zmienne powinny być przekazywane przez referencję”
kolypto
32
Dodaj dodatkowy nawias, aby uniknąć ścisłego ostrzeżenia:end((array_values($yourArray)))
Daniel W.
212

Krótkie i słodkie.

Wymyśliłem rozwiązanie, aby usunąć komunikat o błędzie i zachować formę jednowarstwową i wydajną wydajność:

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

- poprzednie rozwiązanie

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

Uwaga: dodatkowe nawiasy są potrzebne, aby uniknąć PHP Strict standards: Only variables should be passed by reference.

rolacja
źródło
31
Po dokładnie 5 latach, 6 miesiącach i 2 dniach przesłałeś lepszą odpowiedź !! Dziękuję Ci! i dziękuję Przepełnienie stosu !!
Theodore R. Smith
1
Pozdrów odpowiedź, ale dodanie dodatkowych nawiasów wydaje się trochę hackisch. Również phpStorm oznaczy to jako błąd. Dodatkowe informacje dotyczące dodawania dodatkowych nawiasów ( phpsadness.com/sad/51 ). Aby przezwyciężyć błąd, możesz ustawić go jako „2-liniowy”: $array = array_slice($array, -1); $lastEl = array_pop($array);Osobiście uważam, że jest to lepsze (bez parsera „błędu”)
Maurice
3
Możesz użyć dereferencji w następujący sposób: array_slice ($ array, -1) [0]
Vikash
1
Nie możesz, jeśli masz ciągi jako indeks w tablicy
rolacja
3
Ta odpowiedź wciąż wymaga co najmniej dwóch kontroli, aby uniknąć powiadomień PHP. 1. sprawdź, czy array_size() > 1 2. Sprawdź, czy tablica faktycznie jest tablicą. Nadal trzymam się odpowiedzi @Iznogood, ponieważ wbudowana end()funkcja PHP wykonuje całą ciężką pracę w bardziej wydajny sposób.
Ema4rl,
37

Co jest nie tak z array_slice($array, -1)? (Patrz Podręcznik: http://us1.php.net/array_slice )

array_slice()zwraca tablicę. Prawdopodobnie nie to, czego szukasz. Chcesz tego elementu.

Stoutie
źródło
21
Użyj, array_slice($array, -1)[0]aby uzyskać element.
Pang
2
Oto odpowiedź. „end” Zmieniasz wewnętrzny wskaźnik tablicy? Pytanie o kłopoty i bardzo trudne do odczytania!
Gerard ONeill,
Uwielbiam to podejście, chociaż, jak wskazuje @Pang, nie jest do końca kompletne. reset(array_slice($array, -1))to inne podejście (nie spowoduje błędu, jeśli array_slice()zwróci coś „mniejszego” niż tablica jednoelementowa)
rinogo
Najlepsze podejście, ponieważ możesz bezpośrednio zmodyfikować element:array_slice($array, -1)[0] = "";
HAlex
20

Jednym ze sposobów uniknięcia błędów przekazywania przez odwołanie (np. „End (wartości_szablonu ($ foo))”) jest użycie call_user_func lub 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
źródło
Świetne podejście! (wstaw tutaj standardową „To powinna być zaakceptowana odpowiedź”)
Typo
3
Lub po prostu dodaj dodatkową nawias. Krótszy i słodszy:end((array_values($yourArray)))
Dzhuneyt
4
Dodatkowa sztuczka w nawiasach polega na błędzie w PHP i takie podejście nie działa już w późniejszych wersjach PHP (a przynajmniej nie w PHP 7).
Matt Browne,
1
A call_user_funcsztuczka nie działa również w PHP 7. Myślę, że utknąłeś z tworzeniem zmiennej tymczasowej.
Matt Browne,
15

Jeśli nie chcesz modyfikować wskaźnika wewnętrznego (obsługuje zarówno tablice indeksowane, jak i asocjacyjne):

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

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


Jeśli potrzebujesz funkcji narzędzia, która nie modyfikuje wewnętrznego wskaźnika (ponieważ tablica jest przekazywana przez wartość, a funkcja działa na jej kopii):

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

Zauważ, że PHP produkuje kopie „w locie”, tj. Tylko wtedy, gdy są rzeczywiście potrzebne. end()Sam zmienia tablicy więc wewnętrznie kopia tablicy jest generowany.


Zatem następująca alternatywa jest w rzeczywistości szybsza, ponieważ wewnętrznie nie kopiuje tablicy, po prostu tworzy plasterek:

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

Ten „foreach / return” to poprawka do skutecznego zdobycia pierwszego (i tutaj pojedynczego) przedmiotu.


Wreszcie najszybsza alternatywa, ale tylko dla indeksowanych tablic:

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



Dla przypomnienia, oto moja kolejna odpowiedź na pierwszy element tablicy.

Gras Double
źródło
udostępniasz 2 alternatywne implementacje dla array_last funkcji. Po pierwsze stwierdzasz, że $arrayjest on kopiowany, a po drugie, że nie jest kopiowany. Gdzie jest różnica / dlaczego jest kopiowana w pierwszym wdrożeniu, a nie w drugim?
Paul van Leeuwen
1
@PaulvanLeeuwen Zrozumiałem, dlaczego się zdezorientowałeś. Próbowałem wyjaśnić odpowiedź , czy jest lepiej?
Gras Double
10

niesprawdzone: czy to nie zadziała?

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

Ponieważ tablica zwracana przez array_values ​​jest ulotna, nikogo to nie obchodzi, jeśli jej wskaźnik zostanie zresetowany.

i jeśli potrzebujesz klucza, aby to zrobić, myślę, że zrobiłbyś:

<?php
$last_key=end(array_keys($array));
?>
TecBrat
źródło
9

Potrzebuję tego dość często, aby radzić sobie ze stosami, i zawsze jestem zaskoczony, że nie ma natywnej funkcji, która by to zrobiła bez manipulowania tablicą lub jej wewnętrznym wskaźnikiem w jakiejś formie.

Więc zwykle noszę funkcję util, która jest również bezpieczna w przypadku tablic asocjacyjnych.

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

    $keys = array_keys($array);
    return $array[$keys[sizeof($keys) - 1]];
}
thrau
źródło
1
Dobra wiadomość, sprawiają, że jest to funkcja natywna :-) Możesz mieć oko na planowanie wydania tutaj: wiki.php.net/todo/php73 (oczekiwany 13 grudnia 2018 r. W momencie pisania tego tekstu).
Paul van Leeuwen,
9

Aby uzyskać ostatni element tablicy, użyj:

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

Reper

Ierowałem 1000 razy, chwytając ostatni element małych i dużych tablic, które zawierały odpowiednio 100 i 50 000 elementów.

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

Użyłem PHP w wersji 5.5.32.

Westy92
źródło
co z użyciem $ array [array_keys ($ array) [count (array_keys ($ array)) - 1]]?
user2782001
hmm..array_keys wydaje się dość słabo skalować.
user2782001
1
To naprawdę szalone, że duża tablica (0.0002) wyskakuje z elementu i przywraca go z powrotem ... $ val = $ ar [] = $ array_pop ($ ar);
user2782001
1
@ Westy92 Twoje jednostki wydają się błędne w teście porównawczym. Najmniejsza podana liczba to 0,00031 ... mikrosekundy, czyli około 0,3 nanosekundy. Oznaczałoby to, że test wymagał uruchomienia jednego tyknięcia zegara, jeśli masz nowy komputer. Zgaduję, że miałeś na myśli milisekundy, a może nawet sekundy .
cesoid
1
Wartości są wyraźnie niepoprawne o kilka rzędów wielkości. Po co w ogóle skupiać się na wydajności?
istepaniuk
6

end () dostarczy ostatni element tablicy

$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
źródło
1
To rozwiązanie działa, ale zmienia wewnętrzny wskaźnik tablicy, nie sądzę, że jest to właściwy sposób.
UnixAgain
5

Od wersji PHP 7.3 funkcje array_key_firsti array_key_lastzostały wprowadzone.

Ponieważ tablice w PHP nie są ścisłymi typami tablic, tj. Kolekcjami o stałych rozmiarach pól o stałej wielkości, zaczynającymi się od indeksu 0, ale dynamicznie rozszerzaną tablicą asocjacyjną, obsługa pozycji z nieznanymi kluczami jest trudna, a obejścia nie działają zbyt dobrze. Natomiast prawdziwe tablice byłyby bardzo szybko wewnętrznie adresowane za pomocą arytmetyki wskaźników, a ostatni indeks jest już znany w czasie kompilacji poprzez deklarację.

Przynajmniej problem z pierwszą i ostatnią pozycją jest rozwiązany przez wbudowane funkcje od wersji 7.3. Działa to nawet bez ostrzeżeń na literałach tablic po wyjęciu z pudełka:

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

Oczywiście ostatnia wartość to:

$array[array_key_last($array)];
Klon Quasimodo
źródło
1
Dziękujemy za zwrócenie na to uwagi. Dla tych, którzy są chętni do korzystania z tego: proszę nie, że jest to RC w momencie pisania tego tekstu. Premiera filmu planowana jest na grudzień 2018 r.
Paul van Leeuwen
1
To dobra wiadomość. Właśnie opublikowałem polifill / shim w mojej odpowiedzi poniżej, aby ludzie mogli od razu zacząć korzystać z tej składni.
Mark Thomson,
3
$lastValue = end(array_values($array))

Nie dokonuje się modyfikacji wskaźników $ tablicowych. Pozwala to uniknąć

reset($array)

co może nie być pożądane w pewnych warunkach.

Vihaan Verma
źródło
3

Dla mnie:

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

Dzięki inicjatywom:

$last =array_values($array)[count($array - 1)]
Mirko Pagliai
źródło
Podaj kontekst swojego odpowiedzi.
Shawn
2
@Shawn Który kontekst? Nie potrzebuję kontekstu. Dodano kod dla tablic asocjacyjnych.
Mirko Pagliai,
3

Najlepsze odpowiedzi są świetne, ale jak wspomnieli @ paul-van-leeuwen i @ quasimodos-clone, PHP 7.3 wprowadzi dwie nowe funkcje bezpośredniego rozwiązania tego problemu - array_key_first () i array_key_last () .

Możesz zacząć korzystać z tej składni już dziś z następującymi funkcjami wypełniania (lub podkładki).

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

Uwaga: Wymaga PHP 5.4 lub nowszego.

Mark Thomson
źródło
2

Aby to zrobić i uniknąć E_STRICT i nie zadzierać z wewnętrznym wskaźnikiem tablicy, możesz użyć:

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

$last_element = lelement($array);

lelement działa tylko z kopią, więc nie wpływa na wskaźnik tablicy.

Damiene
źródło
2

Inne rozwiązanie:

$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
$lastItem = $array[(array_keys($array)[(count($array)-1)])];
echo $lastItem;
Giuseppe Gallo
źródło
2

Jeszcze jedno możliwe rozwiązanie ...

$last_element = array_reverse( $array )[0];
Charles Garrison
źródło
Brak pracy nad tablicami asocjacyjnymi nie wydaje mi się wystarczającym powodem, aby głosować za mną. Pod względem jakości ta odpowiedź nie jest gorsza niż wiele innych odpowiedzi na to pytanie. Nie rozumiem, dlaczego w tej chwili widzę co najmniej 2 opinie negatywne. (wynik -2). W każdym razie, głosujcie za mną, nie jest tak źle.
Paul van Leeuwen,
2

Co powiesz na:

current(array_slice($array, -1))
  • działa dla tablic asocjacyjnych
  • działa, gdy $array == [](zwraca false)
  • nie wpływa na oryginalną tablicę
Bouke Versteegh
źródło
2

Ostatni element z tablicy uzyskasz łatwo, korzystając z poniższej logiki

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

Nie tylko ostatni element, ale możesz także uzyskać drugi, trzeci i tak dalej, korzystając z poniższej logiki.

dla drugiego ostatniego elementu musisz przekazać tylko cyfrę 2 w powyższej instrukcji, na przykład:
echo ($ array [count ($ array) -2]);

Amzad Khan
źródło
1

Aby uzyskać ostatnią wartość z tablicy:

array_slice($arr,-1,1) ;

W celu usunięcia tablicy ostatniej wartości:

array_slice($arr,0,count($arr)-1) ;
Rishabh
źródło
1
array_slice($arr,-1,1)spowoduje kolejną tablicę o długości 1, a nie ostatni element
Vic
Weźmy przykład: $a=array("red","green","blue","yellow","brown"); print_r(array_slice($a,-1,1)); Wynik:Array ( [0] => brown )
Rishabh
1

Po prostu: $last_element = end((array_values($array)))

Nie resetuje tablicy i nie wyświetla ostrzeżeń typu STRICT.

PS. Ponieważ najczęściej głosowana odpowiedź wciąż nie ma podwójnego nawiasu, przesłałem tę odpowiedź.

Daan
źródło
1

Myślę, że jest to niewielka poprawa w stosunku do wszystkich istniejących odpowiedzi:

$lastElement = count($array) > 0 ? array_values(array_slice($array, -1))[0] : null;
  • Działa lepiej niż end()przy użyciu rozwiązań array_keys(), szczególnie przy dużych tablicach
  • Nie zmodyfikuje wewnętrznego wskaźnika tablicy
  • Nie będzie próbował uzyskać dostępu do niezdefiniowanego przesunięcia dla pustych tablic
  • Działa zgodnie z oczekiwaniami dla pustych tablic, tablic indeksowanych, tablic mieszanych i tablic asocjacyjnych
Adelmar
źródło
Niestety nie działa z tablicami asocjacyjnymi, ponieważ pojedynczy element plasterka może mieć nazwany klucz.
Gras Double
Masz rację, zredagowano, aby dodać poprawkę ( array_valuesdo wycinka z jednym elementem)
Adelmar
1

Użyj funkcji end ().

$array = [1,2,3,4,5];
$last = end($array); // 5
Brian Berneker
źródło
1
Zwróć uwagę, że ta funkcja przesuwa wskaźnik tablicy do tej pozycji.
giovannipds
Zwróć także uwagę, że zostało to opublikowane jako odpowiedź 8 lat wcześniej. stackoverflow.com/a/3687368/1255289
miken32
1

W dzisiejszych czasach wolałbym zawsze mieć tego pomocnika, jak sugerowano w odpowiedzi na php.net/end .

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

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

Dzięki temu wskaźnik pozostanie niezmieniony i nigdy nie będziemy musieli martwić się nawiasami, ścisłymi standardami lub czymkolwiek innym.

giovannipds
źródło
Już wspomniano powyżej: stackoverflow.com/a/45333947/1255289
miken32
0

Uwaga: Dla (PHP 7> = 7.3.0) możemy użyć array_key_last - Pobiera ostatni klucz tablicy

array_key_last ( array $array ) : mixed

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

lokender singh
źródło
1
Zostało to już uwzględnione w wielu innych odpowiedziach.
miken32
ale odpowiedziałem na to wcześniej niż inni
lokender singh
-1

Co jeśli chcesz umieścić ostatni element tablicy w pętli jego tablicy?

Poniższy kod spowoduje powstanie nieskończonej pętli:

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

Rozwiązanie jest oczywiście proste w przypadku tablic niekojarzonych:

$last_element = $array[sizeof ($array) - 1];
foreach ($array as $key => $item) {
 if ($last_element == $item) {
   // something useful here
 }
}
Wadim Podlewski
źródło
2
Wiem o funkcjach end () i reset (). Mój komentarz dotyczył pętli takich jak foreach lub gdy nie można używać tych funkcji, ponieważ funkcja reset resetuje wewnętrzny wskaźnik tablicy, która jest używana w pętli do iteracji. Przepraszam za to, pytanie było prostsze, chciałem tylko podać bardziej zaawansowaną sytuację, z którą spotkałem się w moim projekcie. Z poważaniem.
Vadim Podlevsky
Jest to błędne na wiele sposobów (tablice z duplikatami, nieprecyzyjne porównanie ...) i w żadnym wypadku nie jest tak naprawdę związane z pytaniem.
Tgr
użyj funkcji end ($ array), aby uzyskać ostatni element, dlaczego niepotrzebnie używasz pętli?
Mahak Choudhary
1
@MahakChoudhary Mój komentarz jest dodatkiem do „jak uzyskać ostatni element tablicy, jeśli wykonujesz pewne manipulacje już wewnątrz pętli tej tablicy. Użycie end () resetuje wskaźnik wewnętrzny i przerywa pętlę iteracji. Pozdrawiam!
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
źródło
-1

Począwszy od PHP 7.3, array_key_lastjest dostępny

$lastEl = $myArray[array_key_last($myArray)];
Tagarikdi Djakouba
źródło
Zostało to już wspomniane w wielu innych odpowiedziach.
miken32
-1

Bardzo prosta

$array = array('a', 'b', 'c', 'd');
end($array)
Jasmeen Maradeeya
źródło
Należy wspomnieć, że ma to dziwne zachowanie, jeśli używasz tablic z przerwami. tj. $a = array(); $a[2] = 'c'; $a[1] = 'b'; echo end($a); powrócib
Simon Zyx
Zostało to opublikowane 9 lat temu. stackoverflow.com/a/3687368/1255289
miken32