Який найкращий спосіб отримати останній елемент масиву, не видаляючи його?


427

Добре,

Я знаю все про array_pop(), але це видаляє останній елемент. Який найкращий спосіб отримати останній елемент масиву, не видаляючи його?

EDIT: Ось бонус:

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

або навіть

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

11
Вірити чи не вискакувати, і повернути його - один з найшвидших способів, яким я орієнтувався на це. $ val = $ array [] = array_pop ($ масив); ехо $ вал;
користувач2782001

2
Це питання призвело до багатьох варіантів. Щоб допомогти собі вибрати, я провів порівняння найбільш помітних / чітких варіантів і поділився результатами як окрема відповідь . (: @ user2782001 запропонував мого улюбленого поки що в коментарі вище. :) Дякую всім за внесок!
Пол ван Левен

1
@TheodoreRSmith Коли PHP 7.3 випущений ви могли б розглянути можливість зробити ( це пропозиція на клоні Квазімодо «загальноприйнятий відповідь» (для розгляду) ...
Поль ван Ліувен

Відповіді:


175

Багато відповідей у ​​цій темі дають нам безліч різних варіантів. Щоб мати можливість вибирати з них, мені потрібно було зрозуміти їх поведінку та продуктивність. У цій відповіді я поділюся своїми висновками з вами, порівнювалися з версіями PHP 5.6.38, 7.2.10і 7.3.0RC1( очікується 13 грудня 2018 ).

Параметри, <<option code>>які я перевірю, є:

(згадані функції: array_key_last , array_keys , array_pop , array_slice , array_values , count , end , reset )

Тестові входи ( <<input code>>и), які слід об'єднати з:

  • null =$array = null;
  • порожній =$array = [];
  • last_null =$array = ["a","b","c",null];
  • auto_idx =$array = ["a","b","c","d"];
  • перетасувати =$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; }

Для тестування я буду використовувати 5.6.38, 7.2.10і 7.3.0RC1 Докер контейнери PHP як:

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

Кожна комбінація перерахованих вище <<option code>>s та <<input code>>s буде виконуватися у всіх версіях PHP. Для кожного тестового запуску використовується наступний фрагмент коду:

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

Для кожного запуску це буде вивантажувати останнє отримане останнє значення тестового вводу та друкувати середню тривалість однієї ітерації у фемтосекундах (0,000000000000001-й секунди).

Результати такі:

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

Вищезазначені коди F atal, W arning та N otice перекладаються як:

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

На основі цього результату я роблю такі висновки:

  • новіші версії PHP працюють краще за винятком цих параметрів, які стали значно повільнішими:
    • варіант .6. $x = end((array_values($array)));
    • варіант .8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
  • ці параметри масштабуються найкраще для дуже великих масивів:
    • варіант .5. $x = end($array); reset($array);
    • варіант .7. $x = $array[count($array)-1];
    • варіант .9. $x = $array[] = array_pop($array);
    • варіант 10. $x = $array[array_key_last($array)]; (з PHP 7.3)
  • ці параметри слід використовувати лише для автоіндексованих масивів :
    • варіант .7. $x = $array[count($array)-1];(завдяки використаннюcount)
    • варіант .9. $x = $array[] = array_pop($array);(через присвоєння значення втрачає оригінальний ключ)
  • ця опція не зберігає внутрішній покажчик масиву
    • варіант .5. $x = end($array); reset($array);
  • ця опція є спробою змінити варіант .5. щоб зберегти внутрішній покажчик масиву (але, на жаль, він не масштабує добре для дуже великих масивів)
    • варіант .6. $x = end((array_values($array)));
  • Нова array_key_lastфункція, здається, не має жодного з вищезазначених обмежень, за винятком того, що вона все ще є RC на момент написання цього повідомлення (тому використовуйте RC або чекайте його випуску грудень 2018):
    • варіант 10. $x = $array[array_key_last($array)]; (з PHP 7.3)

Трохи залежно від того, використовуючи масив як стек чи як чергу, ви можете змінити варіант 9.


Якщо ви виявите, що певний варіант відсутній, ви можете перевірити його самостійно, скопіювавши вищевказані фрагменти коду разом, порівнявши його з раніше тестованим варіантом. Щоб додати параметр до цього списку, слід повторно протестувати всі комбінації для порівняльних результатів. Якщо у вас є певний варіант, який, на вашу думку, слід додати, будь ласка, залиште коментар, я маю намір його потім додати (хоча це може зайняти деякий час).
Пол ван Левен

1
Дуже чудова відповідь, але один коментар: для асоціативних масивів варіант 9 також не може бути використаний, оскільки ми присвоюємо ключ до автоіндексованого ключа замість попереднього імені ключа.
Гра "Подвійний"

1
Приємний підсумок! Будь ласка, додайте мою відповідь, використовуючи новий PHP 7.3. функцію $array[array_key_last($array)];до вашого орієнтиру. І будь ласка, дайте мені трохи сповіщення, коли закінчите. Я хотів би побачити результати продуктивності порівняно.
Клон Квазімодо,

2
@sz він в основному створювався з великою впертістю та терпінням, але загальний вибір та багаторядкові функції редагування редактора тексту Sublime допомогли. регенерація зайняла майже добу, тому, якщо мені доведеться це зробити ще раз, я, ймовірно, напишу щось, що автоматично перетворює вихід усіх 210 виконань докера в таблицю :-)
Пол ван Левенен

1
@ quasimodos-clone Я відновив всю таблицю на основі останнього випуску PHP 5, 7 та вашого RC. Я припускаю, що ми захочемо генерувати його ще з грудня, коли він буде фактично випущений. Дякуємо за те, що привернули увагу кожної нової функції.
Пол ван Левен

487

Спробуйте

$myLastElement = end($yourArray);

Щоб скинути його (спасибі @hopeseekr):

 reset($yourArray);

Посилання на посібник

@David Murdoch додав: $myLastElement = end(array_values($yourArray));// and now you don't need to call reset(). На E_STRICT це створює попередження

Strict Standards: Only variables should be passed by reference

Дякую o_O Tync і всім!


38
Користуйтеся, $myLastElement = end(array_values($yourArray));і тепер вам не потрібно дзвонити reset().
Девід Мердок

5
@DavidMurdoch Можливо, але це впевнено змінює оперативну пам’ять та процесор, створюючи тимчасовий масив для значень масиву ...
Теодор Р. Сміт

12
Якщо ваш сервер споживає занадто багато оперативної пам’яті, щоб виклик однієї простої додаткової функції є переривником угод, я пропоную вам переглянути свою конфігурацію та ресурси вашого сервера.
Кріс Бейкер

3
end(array_values())дасть E_STRICT: "Тільки змінні повинні передаватися за посиланням"
kolypto

32
Додайте додаткові дужки, щоб уникнути суворого попередження:end((array_values($yourArray)))
Daniel W.

212

Короткий і милий.

Я придумав рішення, як видалити повідомлення про помилку та зберегти форму з однорядним лідером та ефективну ефективність:

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

- попереднє рішення

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

Примітка. Додаткові дужки потрібні, щоб уникнути PHP Strict standards: Only variables should be passed by reference.


31
Через 5 років, 6 місяців і 2 дні ви надіслали більш чудову відповідь !! Дякую! і дякую Stack Overflow !!
Теодор Р. Сміт

1
Вітайте відповідь, але додавання додаткових дужок відчуває себе трохи хакішем. Також phpStorm позначить це як помилку. Додаткова інформація для додавання додаткових дужок ( phpsadness.com/sad/51 ). Щоб подолати помилку, ви можете зробити це "2-лайнером": $array = array_slice($array, -1); $lastEl = array_pop($array);Особисто я думаю, що це краще (без "помилки" аналізатора)
Моріс

3
Ви можете використовувати перенаправлення так: array_slice ($ масив, -1) [0]
Вікаш

1
Ви не можете, якщо у масиві є рядки як індекс
rolacja

3
На цю відповідь потрібно як мінімум дві перевірки, щоб уникнути повідомлень PHP. 1. Перевірте, чи array_size() > 1 2. Перевірте, чи масив насправді є масивом. Я все ще дотримуюся відповіді від @Iznogood, оскільки вбудована end()функція PHP вже виконує всі наполегливіші дії більш ефективно.
Ema4rl

37

Що не так array_slice($array, -1)? (Див. Посібник: http://us1.php.net/array_slice )

array_slice()повертає масив. Напевно, не те, що ви шукаєте. Ви хочете елемент.


21
Використовуйте array_slice($array, -1)[0]для отримання елемента.
Панг

2
Це відповідь. "end" Зміна внутрішнього вказівника масиву? Просить клопоту, і дуже важко читати!
Джерард ONeill

Подобається такий підхід, хоча, як вказує @Pang, він не зовсім завершений. reset(array_slice($array, -1))інший підхід (який не спричинить помилку, якщо array_slice()поверне щось "менше", ніж одноелементний масив)
rinogo

Найкращий підхід, оскільки ви можете безпосередньо змінити елемент:array_slice($array, -1)[0] = "";
HAlex

20

Один із способів уникнути помилок проходження посилання (наприклад, "end (array_values ​​($ foo))") "- це використовувати call_user_func або 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))));

Чудовий підхід! (тут вставити стандарт "Це має бути прийнята відповідь")
Typo

3
Або просто додайте додатковий парантез. Коротше і солодше:end((array_values($yourArray)))
Джунейт

4
Додатковий фокус дужок покладається на помилку в PHP, і цей підхід більше не працює в пізніших версіях PHP (або, принаймні, не в PHP 7).
Метт Браун

1
І call_user_funcфокус не працює і в PHP 7. Я думаю, ти застряг у створенні тимчасової змінної.
Метт Браун

15

Якщо ви не переймаєтесь зміною внутрішнього вказівника (підтримує як індексований, так і асоціативний масиви):

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

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


Якщо ви хочете функцію утиліти, яка не змінює внутрішній покажчик (оскільки масив передається за значенням, а функція працює на його копії):

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

Зауважте, що PHP створює копії "на ходу", тобто лише за потреби. Theend()Сам змінює масив, тому внутрішньо копія масиву генерується.


Таким чином, наступна альтернатива насправді швидша, оскільки внутрішньо вона не копіює масив, вона просто робить фрагмент:

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

Цей "передбачення / повернення" є налаштуванням для ефективного отримання першого (і тут одного) предмета.


Нарешті, найшвидша альтернатива, але лише для індексованих масивів:

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



Для запису ось ще одна моя відповідь , для першого елемента масиву.


ви надаєте 2 альтернативних реалізації array_lastфункції. Для першого ви заявляєте, що $arrayкопія копіюється, а для другого - це не скопійоване. Де різниця / чому вона копіюється у першій реалізації, а не у другій?
Пол ван Левен

1
@PaulvanLeeuwen Я зрозумів, чому ти заплутався. Я спробував уточнити відповідь , це краще?
Двомісний Грас

10

неперевірено: чи не вдалося б це зробити?

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

Оскільки масив, повернутий array_values, є швидкоплинним, ніхто не піклується, чи не буде скинутий вказівник.

і якщо вам потрібен ключ, щоб піти з ним, я думаю, що ви зробите:

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

9

Мені це потрібно часто, щоб мати справу зі стеками, і я завжди знаходжу себе збентеженим, що немає жодної нативної функції, яка виконує це, не маніпулюючи масивом або його внутрішнім покажчиком у якійсь формі.

Тому я зазвичай виконую утиліту, яка також безпечна для використання в асоціативних масивах.

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

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

1
Хороша новина, вони роблять це натільною функцією :-) Ви можете слідкувати за плануванням випуску тут: wiki.php.net/todo/php73 (очікується 13 грудня 2018 року під час написання цього повідомлення).
Пол ван Левен

9

Щоб отримати останній елемент масиву, використовуйте:

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

Орієнтир

Я повторював 1000 разів, захоплюючи останній елемент малих та великих масивів, що містили відповідно 100 та 50 000 елементів.

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

Я використовував PHP версії 5.5.32.


як щодо використання $ array [array_keys ($ array) [count (array_keys ($ array)) - 1]]?
користувач2782001

hmm..array_keys, схоже, масштабує досить погано.
користувач2782001

1
Насправді з розуму швидше великий масив (0,0002) спливає елемент і поверне його назад ... $ val = $ ar [] = $ array_pop ($ ar);
користувач2782001

1
@ Westy92 Ваші одиниці здаються неправильними на еталоні. Найменше число, яке ви даєте, - 0,00031 ... мікросекунд, що становить приблизно 0,3 наносекунди. Це означає, що ваш тест запустив один годинник, якщо у вас є новий комп'ютер. Я здогадуюсь, ви або мали на увазі мілісекунди, або, можливо, навіть секунди .
цезоїд

1
Значення явно на кілька порядків неправильні. Навіщо зосереджуватись на ефективності взагалі?
істепанюк

6

end () надасть останній елемент масиву

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

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

1
Це рішення працює, але воно змінює внутрішній покажчик масиву, я не думаю, що це правильний шлях.
UnixAgain

5

Станом на PHP версії 7.3 функцій array_key_firstі array_key_lastбуло введено.

Оскільки масиви в PHP не є строгими типами масивів, тобто колекціями фіксованих розмірів полів фіксованого розміру, починаючи з індексу 0, але динамічно розширеного асоціативного масиву, обробка позицій з невідомими клавішами є складною, а обхідні шляхи не дуже добре працюють. На противагу цьому, реальні масиви будуть вирішуватися внутрішньо за допомогою арифметики вказівника дуже швидко, і останній індекс вже відомий під час компіляції шляхом декларації.

Принаймні, проблема з першим і останнім положенням вирішується вбудованими функціями, починаючи з версії 7.3. Це навіть працює без будь-яких попереджень для літералів масиву поза полем:

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

Очевидно, що останнє значення :

$array[array_key_last($array)];

1
Дякуємо, що донесли це до уваги всіх. Для тих, хто прагне скористатися цим: будь ласка, не зазначайте, що це RC на даний момент написання. Реліз запланований на грудень 2018 року.
Пол ван Левенен

1
Це чудова новина. Щойно я опублікував поліфіл / прошивку у своїй відповіді нижче, щоб люди могли почати використовувати цей синтаксис відразу.
Марк Томсон

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

Жодна зміна покажчиків $ масиву не проводиться. Це уникає

reset($array)

що може бути небажаним у певних умовах.


3

Для мене:

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

З товаришами:

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

Укажіть, будь ласка, якийсь контекст для вашої відповіді.
Шон

2
@Shawn Який контекст? Не потрібен контекст. Доданий код для асоціативних масивів.
Мирко Пальяй

3

Найкращі відповіді чудові, але як зазначають @ paul-van-leeuwen та @ quasimodos-clone, PHP 7.3 запровадить дві нові функції для вирішення цієї проблеми безпосередньо - array_key_first () та array_key_last () .

Ви можете почати використовувати цей синтаксис сьогодні за допомогою наступних функцій polyfill (або shim).

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

Застереження: для цього потрібно PHP 5.4 або вище.


2

Для цього і уникайте E_STRICT, а не возитися з внутрішнім вказівником масиву, який ви можете використовувати:

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

$last_element = lelement($array);

lelement працює лише з копією, тому це не впливає на покажчик масиву.



2

Ще одне можливе рішення ...

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

Непрацювання над асоціативними масивами, здається, не є достатньою причиною для того, щоб викликати в мене позитивні вимоги. Якісно ця відповідь не гірша, ніж багато інших відповідей на це питання. Я не розумію, чому я бачу принаймні 2 низових потоки в цей час. (оцінка -2). У будь-якому разі, підкресливши мене, це не так вже й погано.
Пол ван Левен

2

Як щодо:

current(array_slice($array, -1))
  • працює для асоціативних масивів
  • працює, коли $array == [](повертається false)
  • не впливає на вихідний масив

2

Ви отримаєте останній елемент з масиву легко, використовуючи нижче логіку

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

Не тільки останній елемент, але ви також можете отримати другий останній, третій останній і так далі, використовуючи нижче логіку.

для другого останнього елемента вам потрібно передати просто число 2 у наведеному вище твердженні, наприклад:
echo ($ array [count ($ array) -2]);


1

Для отримання останнього значення з масиву:

array_slice($arr,-1,1) ;

Для видалення масиву форм останнього значення:

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

1
array_slice($arr,-1,1)призведе ще один масив довжиною 1, а не останній елемент
Вік

Візьмемо приклад: $a=array("red","green","blue","yellow","brown"); print_r(array_slice($a,-1,1)); Результат:Array ( [0] => brown )
Рішабх

1

Просто: $last_element = end((array_values($array)))

Не скидає масив і не дає STRICT попереджень.

PS. Оскільки відповідь, яка найбільше голосує, все ще не має подвійних дужок, я подав цю відповідь.


1

Я думаю, що це незначне поліпшення всіх існуючих відповідей:

$lastElement = count($array) > 0 ? array_values(array_slice($array, -1))[0] : null;
  • Виступає краще end()або використовує рішення array_keys(), особливо з великими масивами
  • Не змінить внутрішній покажчик масиву
  • Не спробує отримати доступ до невизначеного зміщення для порожніх масивів
  • Буде працювати, як очікувалося, для порожніх масивів, індексованих масивів, змішаних масивів та асоціативних масивів

На жаль, він не працює з асоціативними масивами, оскільки в одному елементі фрагмента може бути названий ключ.
Гра "Подвійний"

Ви маєте рацію, відредаговані, щоб додати виправлення ( array_valuesна одноелементному фрагменті)
Adelmar

1

Використовуйте функцію end ().

$array = [1,2,3,4,5];
$last = end($array); // 5

1
Просто зверніть увагу, що ця функція переміщує вказівник вашого масиву на це положення.
giovannipds

Також зверніть увагу, що це було опубліковано як відповідь 8 років тому. stackoverflow.com/a/3687368/1255289
miken32

1

Сьогодні я вважаю за краще завжди мати цього помічника, як це запропоновано у відповіді php.net/end .

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

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

Це завжди зберігатиме вказівник таким, яким він є, і нам ніколи не доведеться турбуватися про дужки, суворі стандарти чи інше.


Уже згадувалося вище: stackoverflow.com/a/45333947/1255289
miken32

0

Примітка. Для (PHP 7> = 7.3.0) ми можемо використовувати array_key_last - Отримує останню клавішу масиву

array_key_last ( array $array ) : mixed

Посилання: http://php.net/manual/en/function.array-key-last.php


1
Про це вже було висвітлено у кількох інших відповідях.
miken32

але я відповів на це раніше, ніж інші
lokender singh

-1

Що робити, якщо ви хочете отримати останній елемент масиву всередині циклу його масиву?

Код, наведений нижче, призведе до нескінченного циклу:

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

Рішення, очевидно, просте для неасоціативних масивів:

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

2
Я знаю про функції end () та reset (). Мій коментар стосувався циклів, таких як foreach або тоді, коли ви не можете використовувати ці функції, оскільки функція скидання скидає внутрішній покажчик масиву, який використовується в циклі для ітерації. Вибачте за це, питання було простішим, я просто хотів дати більш складну ситуацію, з якою я зіткнувся у своєму проекті. З повагою.
Вадим Підлевський

Це багато в чому помиляється (масиви з дублікатами, неточне порівняння ...) і ні в якому разі не дуже пов'язане з питанням.
Тгр

використовуйте функцію end ($ array) для отримання останнього елемента, чому ви без потреби використовуєте петлі?
Махак Чудхарі

1
@MahakChoudhary Мій коментар є доповненням до «як отримати останній елемент масиву , якщо ви робите деякі маніпуляції вже всередині циклу цього масиву , використовуючи кінець () скидає покажчик innver і розірвати ітерації циклу Привітання ..!
Вадим 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;
}


-1

Дуже просто

$array = array('a', 'b', 'c', 'd');
end($array)

Потрібно згадати, що це має дивну поведінку, якщо ви використовуєте масиви з пробілами. тобто $a = array(); $a[2] = 'c'; $a[1] = 'b'; echo end($a); повернетьсяb
Simon

Це було опубліковано 9 років тому. stackoverflow.com/a/3687368/1255289
miken32

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.