Как получить последний ключ в массиве?

335

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

ajsie
источник
10
Следует указать ассоциативный массив, числовой массив или, если должен работать на обоих.
Джимбо Джонни
часто задаваемый вопрос
Хосуа Марсель Крисано

Ответы:

610

Решение было бы использовать комбинацию endи (цитирование) :key

  • end() продвигает внутренний указатель массива к последнему элементу и возвращает его значение.
  • key() возвращает элемент индекса текущей позиции массива.

Итак, часть кода, подобная этой, должна сделать свое дело:

$array = array(
    'first' => 123,
    'second' => 456,
    'last' => 789, 
);

end($array);         // move the internal pointer to the end of the array
$key = key($array);  // fetches the key of the element pointed to by the internal pointer

var_dump($key);

Будет выводить:

string 'last' (length=4)

т.е. ключ последнего элемента моего массива.

После того, как это будет сделано, внутренний указатель массива будет в конце массива. Как указано в комментариях, вы можете запустить reset()массив, чтобы вернуть указатель на начало массива.

Паскаль МАРТИН
источник
17
@Pim: зависит от того, что OP хочет делать с этим массивом после (может не понадобиться для вызова reset()) ;; но вы правы в указании этой функции, которая может быть полезной.
Паскаль МАРТИН
3
@PascalMARTIN +1 Я думаю, что добавление комментария о сбросе () в вашем ответе будет очень полезно.
Лулу
Этот подход не работает, если массив имеет повторяющиеся значения. например. потому array('a', 'b', 'c', 'd', 'a')что он вернет ключ 0, а не 4.
Marc
2
@Marc этот подход работает правильно, даже если есть повторяющиеся значения.
Джефф
1
@pppp это не работает, потому что ... проверьте, что возвращает end (), а затем снова подумайте;)
forsberg
79

Хотя, end()кажется, самый простой, это не самый быстрый. Более быстрая и гораздо более сильная альтернатива array_slice():

$lastKey = key(array_slice($array, -1, 1, true));

Как говорят тесты , для массива с 500000 элементов это почти в 7 раз быстрее!

Тадей Магайна
источник
98
взволнованный этим ответом, я провел быструю проверку 100 000 итераций, сравнивая (а) end($arr);$key = key($arr);reset($arr);с (б) $key = key(array_slice($arr,-1,1,true));... что привело end()к НАМНОГО быстрее! end () = 0,05326 секунд, array_slice = 8,506 секунд ... да ??
Neokio
54
Встроенные функции PHP были созданы экстремальными ботаниками. Не пытайтесь воссоздать эти функции. Скорее всего, вы делаете что-то намного медленнее, чем оригинал. Если вы не какой-то злой волшебник, конечно.
Ммм
16
end()самый быстрый, потому что он может быть получен из очень простой C-функции, такой как:int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }
Gustav
10
@Gustav Я полагаю, что базовая C-реализация PHP на самом деле имеет внутренний указатель lastна последний элемент. Делая в end()значительной степени O (1). :-)
Eric
15
@dmmd, я уверен, что команда PHP будет очень рада, что их называют ботаниками.
datasn.io
53

я предпочитаю

end(array_keys($myarr))
Рутгер ван Барен
источник
19
вызывает STRICT NOTICE, end ожидает ссылку на переменную
Wiliam
25
Вы можете использовать, end((array_keys($myarr)))чтобы обойти уведомление.
Бен Фортуна
9
@BenFortune Это было исправлено в PHP7: «В PHP 5 использование избыточных скобок вокруг параметра функции могло бы скрыть строгие стандартные предупреждения, когда параметр функции передавался по ссылке. Предупреждение теперь будет всегда выдаваться».
Доминик Шейрлинк
это совершенно ненужное предупреждение! это такие нормальные и обычные вещи на всех других языках!
Азерафати
1
В других языках функции не работают с указателями, не так ли?
июня
52

Начиная с PHP 7.3 (2018) для этого есть (наконец) функция: http://php.net/manual/en/function.array-key-last.php

$array = ['apple'=>10,'grape'=>15,'orange'=>20];
echo array_key_last ( $array )

будет выводить

orange
Патрик Годовски
источник
4
Horray! Я собирался добавить этот ответ. Не могли бы вы выделить версию "PHP 7.3" и 2018 год? Будет легче заметить эту удивительную новость для других
Томаш Вотруба
Также хорошо отметить, что это НЕ влияет на внутренний указатель массива.
Мворисек
30

Просто используйте: echo $array[count($array) - 1];

Адитья Чоудхары
источник
75
Это работает только если у вас есть числовые массивы. Сбой с ассоциированными массивами.
Джереми Дж. Старчер
12
Мало того, что это работает только для числовых массивов, он не показывает ключ, но показывает значение, не так ли?
Нанн
я тоже Джейк, можем ли мы сделать что-то, где мы разделим этот (давайте будем честным) топ Google попал в числовой и ассоциативный, так что у нас есть старая ссылка для обоих ... Я только выяснил, что это было для Assoc после анализа, int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }который интересно, но не очень хорошо для бизнеса, когда у вас ограниченный бюджет времени
LOL
5
Кроме того, даже для числового массива имейте в виду, что числовые массивы не обязательно должны располагаться по порядку или используйте все числа. Это будет работать, если вы явно не присваиваете числовые значения, но если вы это сделаете, то у $a[1] = 1; $a[5] = 5; $a[0] = 0;вас будет массив с ключами (1, 5, 0) в указанном порядке. count($a)даст 3 и $a[2]не определено. Это, конечно, не дает вам 5 обратно.
Даниэль Скарбек
1
Прочтите еще раз вопрос «Как получить последний ключ в массиве?»
20

Не знаю, будет ли это быстрее или нет, но кажется, что так проще сделать, и вы избежите ошибки, не передав функцию в end () ...

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

$array = array(
    'first' => 123,
    'second' => 456,
    'last' => 789, 
);

$keys = array_keys($array);
$last = end($keys);
Райан Хунгате
источник
2
Этот ответ (хотя и технически правильный) является расточительным / неэффективным, поскольку требует создания дополнительного массива (такой же длины, как и оригинал). Это означает, что отходы увеличиваются как исходный массив. Это никогда не должно выбираться из-за эффективного ответа Паскаля МАРТИНА. Я удивлен, что это так много голосов.
mickmackusa
12

По состоянию на PHP7.3 вы можете напрямую обращаться к последнему ключу в (внешнем уровне) массива с помощью array_key_last ()

Определенно укладывает большую часть дебатов на этой странице в постель. Это лучший исполнитель, не страдающий побочными эффектами и прямой, интуитивно понятный метод единого вызова, позволяющий получить именно то, что ищет этот вопрос.

Грубый тест в качестве доказательства: https://3v4l.org/hO1Yf

array_slice() + key():  1.4
end() + key():         13.7
array_key_last():       0.00015

* тестовый массив содержит 500000 элементов, микротайм повторяется 100x, затем усредняется, затем умножается на 1000, чтобы избежать научной записи. Благодарим @MAChitgarha за начальный тест, прокомментированный под ответом @ TadejMagajna .

Это означает, что вы можете получить значение окончательного ключа без:

  1. перемещение указателя массива (который требует двух строк кода) или
  2. сортировка, изменение, всплывающее окно, подсчет, индексирование массива ключей или любое другое дурачество

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

Вот демо :

$array = ["a" => "one", "b" => "two", "c" => "three"];
if (!function_exists('array_key_last')) {
    echo "please upgrade to php7.3";
} else {
    echo "First Key: " , key($array) , "\n";
    echo "Last Key: " , array_key_last($array) , "\n";
    next($array);                 // move array pointer to second element
    echo "Second Key: " , key($array) , "\n";
    echo "Still Last Key: " , array_key_last($array);
}

Вывод:

First Key: a
Last Key: c     // <-- unaffected by the pointer position, NICE!
Second Key: b
Last Key: c     // <-- unaffected by the pointer position, NICE!

Некоторые заметки:

  • array_key_last()является родственной функцией array_key_first () .
  • Обе эти функции являются «невежественными указателями».
  • Обе функции возвращают, nullесли массив пуст.
  • Отброшенные родственные функции ( array_value_first()& array_value_last()) также предложили бы невежественный указатель доступа к элементам bookend, но они, очевидно, не смогли набрать достаточное количество голосов, чтобы воплотиться в жизнь.

Вот несколько соответствующих страниц, обсуждающих новые функции:

ps Если кто-то оценивает некоторые другие методы, вы можете обратиться к этой небольшой коллекции сравнений: ( Демонстрация )

Duration of array_slice() + key():     0.35353660583496
Duration of end() + key():             6.7495584487915
Duration of array_key_last():          0.00025749206542969
Duration of array_keys() + end():      7.6123380661011
Duration of array_reverse() + key():   6.7875385284424
Duration of array_slice() + foreach(): 0.28870105743408
mickmackusa
источник
2
Этот ответ должен быть в верхней части списка. Это просто завершено.
Джон
1
Ух ты, ДВ на ЭТОМ моем ответе? В чем дело, слишком всеобъемлющее / окончательное / объяснительное / поддерживаемое? Пфф. Определенно продолжайте нажимать на сообщения, которые осмелились сообщить. Хорошая работа. Если вы не знаете, кнопка DV предназначена для постов, которые «бесполезны». Пожалуйста, спросите себя, какова ваша цель здесь.
mickmackusa
8

Попробуйте использовать функции array_pop и array_keys следующим образом:

<?php

$array = array(
    'one' => 1,
    'two' => 2,
    'three' => 3
);

echo array_pop(array_keys($array)); // prints three

?>
codaddict
источник
14
Это очень медленно, если в вашем массиве более 1 объекта. Пожалуйста, не делай этого.
Андрей
3
и вызывает STRICT NOTICE, ссылка на переменную
Wiliam
array_pop () будет сокращать исходный массив (удаляя последний элемент). Я не уверен, имеет ли это значение для ОП, но, безусловно, будет иметь значение для других.
Программист
1
На самом деле, нет. В этом примере array_pop()оперирует возвращаемым значением, array_keys()а не исходным массивом.
Петко Боссаков
Поскольку существуют другие более эффективные ответы, которые не вызывают УВЕДОМЛЕНИЕ, я не одобряю этот ответ.
mickmackusa
6

Начиная с PHP> = 7.3 array_key_last()- лучший способ получить последний ключ любого массива. Использование комбинации end(), key()и reset()просто получить последний ключ массива возмутительно.

$array = array("one" => bird, "two" => "fish", 3 => "elephant");
$key = array_key_last($array);
var_dump($key) //output 3

сравните это с

end($array)
$key = key($array)
var_dump($key) //output 3
reset($array)

Вы должны сбросить массив, чтобы указатель был в начале, если вы используете комбинацию end()иkey()

Хилари Окоро
источник
4

Я также хотел бы предложить альтернативное решение этой проблемы.

Предполагая, что все ваши ключи являются числовыми без пробелов, я предпочитаю подсчитать массив, затем минус 1 от этого значения (чтобы учесть тот факт, что ключи массива начинаются с 0.

$array = array(0=>'dog', 1=>'cat');

$lastKey = count($array)-1;
$lastKeyValue = $array[$lastKey];

var_dump($lastKey);
print_r($lastKeyValue);

Это даст вам:

int (1) cat


источник
1
Это не будет работать для массивов, где ключи не являются инкрементальными, например, массив (0 => 'собака', 5 => 'кошка'); $ lastKey вернет неправильное значение
kakoma
@kakoma - Как написано в моем сообщении «Предполагается, что все ваши ключи числовые без пробелов».
Для тех, кто задается вопросом, используйте PHP «array_values», чтобы перевести массив в числовую последовательность. php.net/manual/en/function.array-values.php
1
Поскольку этот ответ касается только части возможностей массива (числовых последовательных массивов с ключами), этот ответ не дает надежного / правильного ответа на обобщенный вопрос ОП. Downvote.
mickmackusa
4

Вы можете использовать это:

$array = array("one" => "apple", "two" => "orange", "three" => "pear");
end($array); 
echo key($array);

Другое решение - создать функцию и использовать ее:

function endKey($array){
end($array);
return key($array);
}

$array = array("one" => "apple", "two" => "orange", "three" => "pear");
echo endKey($array);
Атиф Тарик
источник
1
Этот ответ не дает ничего нового, чего еще нет в этой теме.
Мартин
1
Мартин, никто не использует функцию, чтобы получить результат.
Атиф Тарик
1
Вам нужно добавить 1 строку кода в функцию? Это довольно ненужный интерфейс.
Мартин
1
Мартин, какая одна строчка.
Атиф Тарик
2
линия в вашей функции
Мартин
3
$arr = array('key1'=>'value1','key2'=>'value2','key3'=>'value3');
list($last_key) = each(array_reverse($arr));
print $last_key;
// key3
voodoo417
источник
2
Обращение всего массива только для получения одного значения, безусловно, менее эффективно, чем метод PascalMARTIN. Хотя это технически правильно, его никогда не следует использовать вместо подхода Паскаля.
mickmackusa
3

Я просто взял вспомогательную функцию у Ксандера и улучшил ее ответами:

function last($array){
  $keys = array_keys($array);
  return end($keys);
}


$arr = array("one" => "apple", "two" => "orange", "three" => "pear");    
echo last($arr);
echo $arr(last($arr));
Стив
источник
1

Попробуйте это с array_reverse().

 $arr = array(
     'first' => 01,
     'second' => 10,
     'third' => 20, 
 );  
 $key = key(array_reverse($arr));
 var_dump($key);
Вишал Кумар
источник
1

Странно, но почему в этой теме нет такого ответа:

$lastKey = array_keys($array)[count($array)-1];

Alex
источник
0
$array = array(
    'something' => array(1,2,3),
    'somethingelse' => array(1,2,3,4)
);

$last_value = end($array);
$last_key = key($array); // 'somethingelse'

Это работает, потому что PHP перемещает свой указатель массива внутри для $ array

Scottymeuk
источник
2
Это копия метода PascalMARTIN. Пожалуйста, сохраните эту страницу и удалите ваш поздний / дублированный ответ. Downvoted.
mickmackusa
0

Лучшее возможное решение, которое также может быть использовано при использовании inline:

end($arr) && false ?: key($arr)

Это решение является только выражением / заявлением и обеспечивает хорошее, а не наилучшее из возможных результатов.

Пример использования встроенного примера:

$obj->setValue(
    end($arr) && false ?: key($arr) // last $arr key
);


ОБНОВЛЕНИЕ: В PHP 7.3+: используйте (конечно) недавно добавленный array_key_last()метод.

mvorisek
источник