Упорядочены ли PHP-ассоциативные массивы?
Я пришел из фона Python и похожий тип данных Python (словарь) представляет собой неупорядоченный набор пар ключ-значение.
Мне интересно, являются ли PHP-ассоциативные массивы неупорядоченными? Они кажутся заказанными.
$test = array(
'test' => 'test',
'bar' => 'bar',
);
var_dump($test);
var_dump(array_slice($test, 0, 1));
Тест всегда идет перед баром, и я могу разрезать этот массив, как вы видите. Так всегда ли это гарантированно будет заказываться в разных версиях php? Является ли порядок только тем порядком, с которым я объявил массив? Так что-то внутренне указывает 'test', чтобы поместить [0] в массив? Я прочитал http://php.net/manual/en/language.types.array.php но это не проливает слишком много света на эту проблему. Я ценю ваши ответы. Ty
5 ответов
PHP ассоциативные массивы (а также числовые массивы) упорядочены, и PHP предоставляет различные функции для работы с порядком ключей массива, такие как ksort()
, uksort()
, а также krsort()
Кроме того, PHP позволяет объявлять массивы с числовыми ключами не по порядку:
$a = array(3 => 'three', 1 => 'one', 2 => 'two');
print_r($a);
Array
(
[3] => three
[1] => one
[2] => two
)
// Sort into numeric order
ksort($a);
print_r($a);
Array
(
[1] => one
[2] => two
[3] => three
)
Массив в PHP на самом деле является упорядоченной картой. Карта - это тип, который связывает значения с ключами. Этот тип оптимизирован для нескольких различных применений; его можно рассматривать как массив, список (вектор), хеш-таблицу (реализацию карты), словарь, коллекцию, стек, очередь и, возможно, больше. Поскольку значения массива могут быть другими массивами, деревья и многомерные массивы также возможны.
В документации говорится:
An array in PHP is actually an ordered map.
Так что да, они всегда заказаны. Массивы реализованы в виде хеш-таблицы.
Массив упорядочен, но это не означает, что ключи отсортированы, это означает, что они расположены в заданном порядке. Где точный порядок не указан, но, похоже, это порядок, в котором вы ввели в него пары ключ-значение.
Чтобы понять это, подумайте, что значит не получать заказ? Хорошо подумайте об отношении в реляционной базе данных. Отношение не является внутренне упорядоченным: когда вы обращаетесь к нему с помощью запроса, база данных, если вы не предоставите предложение order, может возвращать те же данные в любом порядке. Даже если данные не были изменены, одни и те же данные могут быть возвращены в другом порядке.
Из руководства по PHP:
Массивы упорядочены. Порядок может быть изменен с использованием различных функций сортировки. Смотрите раздел функции массива для получения дополнительной информации.
Я полагался на тот факт, что они заказаны, и это работало последовательно в каждом проекте, который у меня был.
Это не простой вопрос. Документация в данном случае подсказывает неочевидные моменты в разработке, например:
$a = [0 => 'first', 1 => 'second', 3 => 'fourth'];
$a[2] = 'third';
foreach ($a as $element) print($element . "\n");
Здравый смысл подсказывает нам, что при итерации этого массива мы увидим «третий» как третий элемент, но это не так:
first
second
fourth
third
Потому что элементы хранятся в том порядке, в котором они были добавлены, а 0-1-2-3 — это просто ключ, а не порядок. Обычно документация предполагает, что элементы массива имеют некоторый порядок, который явно указан в документации. Это означает, что вы можете получить доступ к: первому элементу, n-элементу, последнему элементу. Но управлять ими напрямую не представляется возможным. То есть можно получить последний элемент, добавить в конец (push/pop), можно получить первый — сдвиг, можно перебирать их (foreach), но без кода получить n-элемент не получится. или поместить элемент в определенную позицию без дополнительного кода. Ну и вопрос - как можно полагаться на этот приказ, если он по каким-то причинам необходим.