Получить первый ключ в (возможно) ассоциативном массиве?

673

Какой лучший способ определить первый ключ в возможно ассоциативном массиве? Сначала я подумал, что нужно просто выделить массив, а затем сразу же сломать его, например:

foreach ($an_array as $key => $val) break;

Таким образом, ключ $содержит первый ключ, но это кажется неэффективным. У кого-нибудь есть лучшее решение?

  • 4
    Почему неэффективный foreach?
  • 1
    По сравнению со всеми ответами, foreach по-прежнему является самой быстрой FIDDLE, PHP 5.3 , мой тест localhost на PHP 5.5 показывает, что разница немного в пользу foreach.
Показать ещё 5 комментариев
Теги:
arrays

20 ответов

1194
Лучший ответ

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

reset($array);
$first_key = key($array);

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

Не забудьте вызвать reset, или вы можете получить любой из ключей в массиве. Вы также можете использовать end вместо reset, чтобы получить последний ключ.

Если вы хотите, чтобы ключ получил первое значение, reset действительно возвращает его:

$first_value = reset($array);

Есть один особый случай, который нужно учесть (хотя сначала проверьте длину массива):

$arr1 = array(false);
$arr2 = array();
var_dump(reset($arr1) === reset($arr2)); // bool(true)
  • 126
    Как примечание, reset() также возвращает первый элемент (значение, а не ключ) любого массива, что также может быть удобно.
  • 5
    В документации к reset() есть комментарий о том, что Don't use reset () `, чтобы получить первое значение ассоциативного массива. Он отлично работает для настоящих массивов, но неожиданно работает с объектами Iterator. bugs.php.net/bug.php?id=38478 `Это все еще правда? Я не совсем понимаю
Показать ещё 11 комментариев
70

array_keys возвращает массив ключей. Возьмите первую запись. В качестве альтернативы вы можете вызвать reset в массиве, а затем key. Последний подход, вероятно, немного быстрее (Thoug я его не тестировал), но он имеет побочный эффект сброса внутреннего указателя.

  • 46
    Просто (позднее) примечание для будущих читателей: последний подход не просто «немного» быстрее. Существует большая разница между итерацией всего массива, сохранением каждого ключа в другом вновь созданном массиве и запросом первого ключа массива в виде строки.
  • 3
    Почему неэффективный foreach как оп в этом вопросе по сравнению со всеми этими ответами?
Показать ещё 6 комментариев
49

Интересно, что цикл foreach на самом деле является наиболее эффективным способом этого.

Поскольку OP специально задал вопрос об эффективности, следует отметить, что все текущие ответы на самом деле намного менее эффективны, чем foreach.

Я сделал тест на php 5.4, а метод указателя reset/key (принятый ответ) примерно в 7 раз медленнее, чем foreach. Другие подходы, управляющие всем массивом (array_keys, array_flip), очевидно, еще медленнее, чем при работе с большим массивом.

Foreach вообще неэффективен, не стесняйтесь использовать его!

Изменить 2015-03-03:

Запрошены тестовые сценарии, у меня нет оригиналов, но вместо этого были сделаны новые тесты. На этот раз я нашел foreach примерно в два раза быстрее, чем reset/key. Я использовал массив из 100 ключей и запускал каждый метод миллион раз, чтобы получить заметную разницу, здесь код простого теста:

$array = [];
for($i=0; $i < 100; $i++)
    $array["key$i"] = $i;

for($i=0, $start = microtime(true); $i < 1000000; $i++) {
    foreach ($array as $firstKey => $firstValue) {
        break;
    }
}
echo "foreach to get first key and value: " . (microtime(true) - $start) . " seconds <br />";

for($i=0, $start = microtime(true); $i < 1000000; $i++) {
    $firstValue = reset($array);
    $firstKey = key($array);
}
echo "reset+key to get first key and value: " . (microtime(true) - $start) . " seconds <br />";

for($i=0, $start = microtime(true); $i < 1000000; $i++) {
    reset($array);
    $firstKey = key($array);
}
echo "reset+key to get first key: " . (microtime(true) - $start) . " seconds <br />";


for($i=0, $start = microtime(true); $i < 1000000; $i++) {
    $firstKey = array_keys($array)[0];
}
echo "array_keys to get first key: " . (microtime(true) - $start) . " seconds <br />";

На моем php 5.5 выходы:

foreach to get first key and value: 0.15501809120178 seconds 
reset+key to get first key and value: 0.29375791549683 seconds 
reset+key to get first key: 0.26421809196472 seconds 
array_keys to get first key: 10.059751987457 seconds

reset + ключ http://3v4l.org/b4DrN/perf#tabs
foreach http://3v4l.org/gRoGD/perf#tabs

  • 3
    У вас есть где-нибудь эталонные тесты? Как то, как вы тестировали и так далее. В любом случае, спасибо за их запуск!
  • 0
    Я хотел бы указать на тот факт, что во всем тесте используется один и тот же массив. Я думаю, что этот факт существенно влияет на подход foreach. Как упомянуто в комментариях к ответу @donquixote выше - foreach внутренне копирует массив. Я могу себе представить, что эта копия используется повторно во время выполнения теста, поскольку предотвращение копирования в массив увеличивает производительность только в этом тесте.
Показать ещё 2 комментария
33

key($an_array) предоставит вам первый ключ

edit per Blixt: вы должны называть reset($array); до key($an_array) до reset указателем на начало массива.

  • 6
    Помните, что указатель массива может не находиться на первом элементе, смотрите мой ответ.
  • 0
    Я думаю, что этот ответ поможет моему случаю без сброса, потому что я сначала проверяю, что массив имеет только один элемент. Спасибо
21

Если эффективность для вас не так важна, вы можете использовать array_keys($yourArray)[0] в PHP 5.4 (и выше).

<сильные > Примеры:

# 1
$arr = ["my" => "test", "is" => "best"];    
echo array_keys($arr)[0] . "\r\n"; // prints "my"


# 2
$arr = ["test", "best"];
echo array_keys($arr)[0] . "\r\n"; // prints "0"

# 3
$arr = [1 => "test", 2 => "best"];
echo array_keys($arr)[0] . "\r\n"; // prints "1"

Преимущество над решением:

list($firstKey) = array_keys($yourArray);

заключается в том, что вы можете передать array_keys($arr)[0] в качестве параметра функции (т.е. doSomething(array_keys($arr)[0], $otherParameter)).

НТН

  • 3
    array_keys($arr)[0] ли array_keys($arr)[0] ?
  • 5
    Это в PHP 5.4. Это называется array dereferencing . См. Например: schlueters.de/blog/archives/…
Показать ещё 1 комментарий
21
list($firstKey) = array_keys($yourArray);
  • 1
    Это, наверное, не самый эффективный.
  • 3
    @Яда, да, но это может быть заметно в редких случаях; в большинстве случаев удобочитаемость и ремонтопригодность имеют гораздо большее значение; и я также предпочитаю решение, которое не изменяет исходные объекты / массивы: например, reset ($ ar); $ key = key ($ ar); - это не всегда хорошая идея, я бы предпочел выбрать решение MartyIX, которое является более кратким, чем мое, например: array_keys ($ ar) [0];
18

Вы можете попробовать

array_keys($data)[0]
11
$myArray = array(
    2 => '3th element',
    4 => 'first element',
    1 => 'second element',
    3 => '4th element'
);
echo min(array_keys($myArray)); // return 1
  • 0
    Это полностью решило мою проблему, используя только max() .
  • 0
    @jurgemaister max() доза не возвращает первый ключ ассоциированного массива. max возвращает максимальное значение списка или массива элементов
Показать ещё 2 комментария
9

Найдите следующее:

$yourArray = array('first_key'=> 'First', 2, 3, 4, 5);
$keys   =   array_keys($yourArray);
echo "Key = ".$keys[0];

Я думаю, что это сработает.

8

Для 2018+

Начиная с PHP 7.3, существует array_key_first() которая достигает именно этого:

$array = ['foo' => 'lorem', 'bar' => 'ipsum'];
echo array_key_first($array); // 'foo'

Документация доступна здесь.

8

Это также может быть решением.

$first_key = current(array_flip($array));

Я тестировал его, и он работает.

  • 3
    array_flip (): может переворачивать только значения STRING и INTEGER!
3

Чтобы улучшить решение Webmut, я добавил следующее решение:

$firstKey = array_keys(array_slice($array, 0, 1, TRUE))[0];

Результат для PHP 7.1:

foreach to get first key and value: 0.048566102981567 seconds 
reset+key to get first key and value: 0.11727809906006 seconds 
reset+key to get first key: 0.11707186698914 seconds 
array_keys to get first key: 0.53917098045349 seconds 
array_slice to get first key: 0.2494580745697 seconds 

Если я делаю это для массива размером 10000, то результаты становятся

foreach to get first key and value: 0.048488140106201 seconds 
reset+key to get first key and value: 0.12659382820129 seconds 
reset+key to get first key: 0.12248802185059 seconds 
array_slice to get first key: 0.25442600250244 seconds 

Метод array_keys истекает через 30 секунд (всего лишь с 1000 элементами, время для остальных примерно одинаково, но метод array_keys имеет около 7,5 секунд).

3
 $arr = array('key1'=>'value1','key2'=>'value2','key3'=>'key3');
 list($first_key) = each($arr);
 print $first_key;
 // key1
2

Лучший способ, который работал у меня, -

array_shift(array_keys($array))

array_keys получает массив ключей из начального массива, а затем array_shift вырезает из него значение первого элемента. Для этого вам понадобится PHP 5.4+.

1

Это самый простой способ, который я когда-либо нашел. Быстрая и только две строки кода: -D

$keys = array_keys($array);
echo $array[$keys[0]];
0

php73:

$array = ['a' => '..', 'b' => '..'];

array_key_first($array); // 'a'
array_key_last($array); // 'b';

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

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

Сегодня мне пришлось искать первый ключ моего массива, возвращенный запросом POST. (И обратите внимание на номер для идентификатора формы и т.д.)

Ну, я нашел это: Вернуть первый ключ ассоциативного массива в PHP

http://php.net/key

Я сделал это, и он работает.

    $data = $request->request->all();
    dump($data);
    while ($test = current($data)) {
        dump($test);
        echo key($data).'<br />';die();
        break;
    }

Может быть, это будет 15 минут другого парня. КДМ.

0

Вы можете попробовать это. Чтобы получить первое значение массива: -

<?php
        $large_array = array('foo' => 'bar', 'hello' => 'world');
        var_dump(current($large_array));
?>

Чтобы получить первый ключ массива

<?php
        $large_array = array('foo' => 'bar', 'hello' => 'world');
        $large_array_keys = array_keys($large_array);
        var_dump(array_shift($large_array_keys));
?>
0

Однострочный:

$array = array('key1'=>'value1','key2'=>'value2','key3'=>'key3');
echo key( array_slice( $array, 0, 1, true ) );

# echos 'key1'
-2

Вы можете играть с вашим массивом

$daysArray = array('Monday', 'Tuesday', 'Sunday');
$day = current($transport); // $day = 'Monday';
$day = next($transport);    // $day = 'Tuesday';
$day = current($transport); // $day = 'Tuesday';
$day = prev($transport);    // $day = 'Monday';
$day = end($transport);     // $day = 'Sunday';
$day = current($transport); // $day = 'Sunday';

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

редактировать

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

  • 1
    Это значения, а не ключи.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню