Каков наилучший способ получить последний элемент массива, не удаляя его?

428

В порядке,

Я все знаю array_pop(), но это удаляет последний элемент. Каков наилучший способ получить последний элемент массива, не удаляя его?

РЕДАКТИРОВАТЬ: Вот бонус:

$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_pop ($ массив); echo $ val;
user2782001
2
Этот вопрос привел ко многим вариантам. Чтобы помочь себе выбрать, я провел некоторое сравнение наиболее заметных / отличных вариантов и поделился результатами в виде отдельного ответа . (: @ user2782001 предложил мой любимый до сих пор в комментарии выше. :) Спасибо всем за участие!
Поль ван Леувен
1
@TheodoreRSmith Когда PHP 7.3 выпущен вы могли бы рассмотреть возможность сделать ( это предложение на клоне Квазимодо «общепринятый ответ» (для рассмотрения) ...
Поль ван Лиувен

Ответы:

177

Многочисленные ответы в этой теме предоставляют нам много разных вариантов. Чтобы иметь возможность выбирать из них, мне нужно было понять их поведение и производительность. В этом ответе я поделюсь своими выводами с вами, сравнивались с версиями 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>>объединяются с:

  • нуль =$array = null;
  • пусто =$array = [];
  • last_null =$array = ["a","b","c",null];
  • auto_idx =$array = ["a","b","c","d"];
  • shuffle =$array = []; $array[1] = "a"; $array[2] = "b"; $array[0] = "c";
  • 100 =$array = []; for($i=0;$i<100;$i++) { $array[] = $i; }
  • 100000 =$array = []; for($i=0;$i<100000;$i++) { $array[] = $i; }

Для тестирования я буду использовать Docker-контейнеры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);

Для каждого запуска это будет var_dump последнего полученного последнего значения входных данных теста и выводит среднюю продолжительность одной итерации в фемтосекундах (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 выполнений докера в таблицу :-)
Paul van Leeuwen,
1
@ quasimodos-clone Я восстановил всю таблицу на основе последней версии PHP 5, 7 и вашего RC. Я предполагаю, что мы захотим сгенерировать его снова в декабре, когда он будет выпущен. Спасибо за то, что обратили внимание на эту новую функцию.
Пол ван Леувен
487

Пытаться

$myLastElement = end($yourArray);

Чтобы сбросить его (спасибо @hopeseekr):

 reset($yourArray);

Ссылка на руководство

@ Дэвид Мердок добавил: $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

Спасибо о_О Тынк и всем!

Iznogood
источник
38
Используйте $myLastElement = end(array_values($yourArray));и теперь вам не нужно звонить reset().
Дэвид Мердок
5
@DavidMurdoch Возможно, но он, безусловно, действительно производит в оперативной памяти и ЦП, создавая временный массив для значений массива ...
Теодор Р. Смит
12
Если ваш сервер потребляет слишком много оперативной памяти, так что вызов одной простой дополнительной функции является прерывателем, я предлагаю вам еще раз проверить конфигурацию и ресурсы вашего сервера.
Крис Бейкер
3
end(array_values())даст E_STRICT: «Только переменные должны быть переданы по ссылке»
Колыпто
32
Добавьте дополнительные скобки, чтобы избежать строгого предупреждения:end((array_values($yourArray)))
Даниэль В.
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.

rolacja
источник
31
Ровно через 5 лет, 6 месяцев и 2 дня вы отправили более качественный ответ !! Спасибо! и спасибо, переполнение стека!
Теодор Р. Смит
1
Приветствую ответ, но добавление лишних скобок кажется немного хакишом. Также phpStorm пометит это как ошибку. Дополнительная информация для добавления дополнительных скобок ( phpsadness.com/sad/51 ). Чтобы преодолеть ошибку, вы могли бы сделать это «2-строчным»: $array = array_slice($array, -1); $lastEl = array_pop($array);лично я думаю, что это лучше (без «ошибки» синтаксического анализатора)
Морис
3
Вы можете использовать разыменование следующим образом: array_slice ($ array, -1) [0]
Vikash
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()возвращает массив. Вероятно, не то, что вы ищете. Вы хотите элемент.

Stoutie
источник
21
Используйте, array_slice($array, -1)[0]чтобы получить элемент.
Пан
2
Это ответ. "конец" Изменение внутреннего указателя массива? Просят неприятностей, и очень трудно читать!
Джерард 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))));
Warbo
источник
Отличный подход! (вставьте стандарт «Это должен быть принятый ответ» здесь)
Опечатка
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 создает копии «на лету», т.е. только тогда, когда это действительно необходимо. end()Сам изменяет массив, поэтому внутренне копия массива генерируется.


Таким образом, следующая альтернатива на самом деле быстрее, поскольку внутренне она не копирует массив, а просто создает фрагмент:

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

Этот «foreach / return» является твиком для эффективного получения первого (и здесь единственного) элемента.


Наконец, самая быстрая альтернатива, но только для индексированных массивов:

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



Для записи, вот еще один мой ответ , для первого элемента массива.

Гра Двухместный
источник
Вы предоставляете 2 альтернативные реализации для array_lastфункции. Для первого вы заявляете, что $arrayскопировано, а для второго, что оно не копируется. В чем разница / почему она копируется в первой реализации, а не во второй?
Пол ван Леувен
1
@PaulvanLeeuwen Я понял, почему ты запутался. Я попытался уточнить ответ , это лучше?
Gras Double
10

не проверено: не будет ли это работать?

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

Поскольку массив, возвращаемый array_values, является мимолетным, никому нет дела, если его указатель сброшен.

и если вам нужен ключ, чтобы пойти с ним, я думаю, вы бы сделали:

<?php
$last_key=end(array_keys($array));
?>
TecBrat
источник
9

Мне нужно это довольно часто, чтобы иметь дело со стеками, и я всегда нахожу себя сбитым с толку, что нет нативной функции, которая делает это без манипулирования массивом или его внутренним указателем в какой-либо форме.

Поэтому я обычно ношу с собой функцию util, которую также безопасно использовать в ассоциативных массивах.

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

    $keys = array_keys($array);
    return $array[$keys[sizeof($keys) - 1]];
}
thrau
источник
1
Хорошая новость, они делают ее встроенной функцией :-) Вы можете следить за планированием ее выпуска здесь: wiki.php.net/todo/php73 (ожидается 13 декабря 2018 года на момент написания этой статьи).
Пол ван Леувен
9

Чтобы получить последний элемент массива, используйте:

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

эталонный тест

Я перебрал 1000 раз, взяв последний элемент из маленьких и больших массивов, которые содержали 100 и 50000 элементов соответственно.

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.

Westy92
источник
как насчет использования $ array [array_keys ($ array) [count (array_keys ($ array)) - 1]]?
user2782001
хм .. array_keys, кажется, масштабируется довольно плохо.
user2782001
1
На самом деле, большой массив (0,0002) быстрее извлекает элемент и возвращает его обратно ... $ val = $ ar [] = $ array_pop ($ ar);
user2782001
1
@ Westy92 Похоже, ваши юниты в тесте неверны. Наименьшее число, которое вы даете, составляет 0,00031 ... микросекунд, что составляет около 0,3 наносекунд. Это означало бы, что вашему тесту потребовался один такт, если у вас новый компьютер. Я предполагаю, что вы имели в виду миллисекунды или даже секунды .
cesoid
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
Ajith
источник
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
Это отличные новости. Я только что опубликовал polyfill / shim в своем ответе ниже, чтобы люди могли сразу начать использовать этот синтаксис.
Марк Томсон
3
$lastValue = end(array_values($array))

В указатели $ array не вносятся изменения. Это позволяет избежать

reset($array)

что может быть нежелательно в определенных условиях.

Вихан Верма
источник
3

Для меня:

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

С ассоциациями:

$last =array_values($array)[count($array - 1)]
Мирко Пальяй
источник
Пожалуйста, предоставьте некоторый контекст для вашего ответа.
Шон
2
@ Показать какой контекст? Не нужен контекст. Добавлен код для ассоциативных массивов.
Мирко Пальяй
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 работает только с копией, поэтому он не влияет на указатель массива.

Damiene
источник
2

Другое решение:

$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
$lastItem = $array[(array_keys($array)[(count($array)-1)])];
echo $lastItem;
Джузеппе Галло
источник
2

Еще одно возможное решение ...

$last_element = array_reverse( $array )[0];
Чарльз Гаррисон
источник
Не работа над ассоциативными массивами не кажется мне достаточной причиной, чтобы понизить голос. По качеству этот ответ не хуже многих других ответов на этот вопрос. Я не понимаю, почему я вижу по крайней мере 2 понижения голосов в это время. (оценка -2). Во всяком случае, upvote для меня, это не так уж плохо.
Пол ван Леувен
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) ;
Rishabh
источник
1
array_slice($arr,-1,1)приведет к другому массиву длиной 1, а не к последнему элементу
Vic
Давайте рассмотрим пример: $a=array("red","green","blue","yellow","brown"); print_r(array_slice($a,-1,1)); Результат:Array ( [0] => brown )
Rishabh
1

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

Не сбрасывает массив и не выдает СТРОГО предупреждения.

PS. Поскольку ответ с наибольшим количеством голосов до сих пор не содержит двойных скобок, я отправил этот ответ.

Даан
источник
1

Я думаю, что это небольшое улучшение всех существующих ответов:

$lastElement = count($array) > 0 ? array_values(array_slice($array, -1))[0] : null;
  • Выполняет лучше, чем end()или использование решений array_keys(), особенно с большими массивами
  • Не будет изменять внутренний указатель массива
  • Не будет пытаться получить доступ к неопределенному смещению для пустых массивов.
  • Будет работать должным образом для пустых массивов, индексированных массивов, смешанных массивов и ассоциативных массивов.
Adelmar
источник
К сожалению, он не работает с ассоциативными массивами, потому что отдельный элемент слайса может иметь именованный ключ.
Двойной Гра
Вы правы, отредактировано, чтобы добавить исправление ( array_valuesдля одноэлементного среза)
Адельмар
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
?>

Это всегда будет держать указатель как есть, и нам никогда не придется беспокоиться о скобках, строгих стандартах или чем-то еще.

giovannipds
источник
Уже упоминалось выше: 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

Lokender Singh
источник
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 или while, где вы не можете использовать эти функции, потому что функция сброса сбрасывает внутренний указатель массива, который используется в цикле для итерации. Извините за это, вопрос был более простым, я просто хотел дать более сложную ситуацию, с которой я столкнулся в своем проекте. С наилучшими пожеланиями.
Вадим Подлевский
Это неправильно во многих отношениях (массивы с дубликатами, нестрогое сравнение ...) и в любом случае не имеет отношения к вопросу.
Tgr
используйте функцию end ($ array), чтобы получить последний элемент, почему вы без необходимости используете циклы?
Махак Чоудхари
1
@MahakChoudhary Мой комментарий является дополнением к «как получить последний элемент массива, если вы делаете какие-то манипуляции уже внутри цикла этого массива. Использование end () сбросит указатель innver и прервет цикл итерации. Приветствия!
Вадим Подлевский
-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
источник
-1

Начиная с PHP 7.3, array_key_lastдоступно

$lastEl = $myArray[array_key_last($myArray)];
Тагарикди Джакоуба
источник
Это уже упоминалось во многих других ответах.
miken32
-1

Очень просто

$array = array('a', 'b', 'c', 'd');
end($array)
Джасмин Марадея
источник
Следует отметить, что это странное поведение, если вы используете массивы с пробелами. то есть $a = array(); $a[2] = 'c'; $a[1] = 'b'; echo end($a); вернетсяb
Simon Zyx
Это было опубликовано 9 лет назад. stackoverflow.com/a/3687368/1255289
miken32
-1

мое простое решение, красивое и простое для понимания.

array_reverse($array)[0];
Альпер Айдингюль
источник
Так просто это было опубликовано 3 года назад. stackoverflow.com/a/38977466/1255289
miken32