Все ленты — последние статьи

Массивы: функции, приемы, многомерность

Дмитрий Лебедев

2001-01-13

То полезное в работе с массивами, чего многие не знают.

Для тех, кому интересно "глубинное" описание принципов работы массиовов в php, могут прочесть вот это. А я поговорю более приземленно.

Начнем с того, что "array" — тип данных, такой же, как integer или string. Если переменная $array — массив, то gettype($array) выдаст "array" (имя переменной взято "от фонаря", и к типу данных оно отношения не имеет), а is_array($array) выдаст true.

Теперь про индексы массива. Кстати, про слово "индекс". Год назад я задался вопросом, что же оно значит, а то "index.htm" было первым и чуть ли не единственным, что приходило в голову. Но я вспомнил! На конвертах бумажной почты была такая надпись "индекс почтового отделения" с трафаретом под цифры. Значит, индексы в массиве — указатели на его элементы :).

 

PHP поддерживает как скалярные (0, 1, 2…), так и ассоциативные ("a", "b", "c") индексы массивов. Ассоциативными массивами пользуются, например, в функциях работы с MySQL:

$row = mysql_fetch_array($result);
print ($row["field1"]. $row["field2"]. $row["field3"]);

Нет надобности объяснять, чем удобны ассоциативные массивы.

Теперь о создании массивов. Первое средство — функция array:

$array = array($val1, $val2, $val3);
$array2 = array($key1 => $val1, $key2 => $val2, $key3 => $val3);

В первом случае получится скалярный массив, во втором — ассоциативный.

Можно создать массив, попросту указав индекс и значение.

$array[$key] = $val;

Переменная $array, если она не существовала до этого, станет массивом, а в ячейку с индексом $key (не обязательно 0) помещается значение $val. Но самое красивое в php — отсутствие необходимости указывать индекс ячейки!

$new_array[] = "0"; // то же самое, что $new_array[0] = "0"
$new_array[] = "1"; // то же самое, что $new_array[1] = "1"

М-м… что-то я уже скатился до руководства по PHP! Это все там написано :). Кстати, мы часто делаем вывод переменной в тексте так:

print ("test $variable text");

Если попытаться вывести так же элемент массива, ничего не получится. Загляните в мануал, там приведены наглядные примеры на эту тему.

Функции, которые часто приходится использовать для работы с массивами — это sizeof (размер массива) и list & each (выбирают из каждого массива имя элемента и его значение).

Чтобы обработать все элементы скалярного массива, в котором (ВНИМАНИЕ!) индексы элементов представяют собой сплошной числовой ряд (от 0 до $n), достаточно использовать sizeof и цикл:

for ($i=0;$i<sizeof($array);$i++) {

};

Если элементы начинаются не с 0, а с известного $m, тогда можно действовать так:

for ($i=$m;$i<sizeof($array)+$m;$i++) {

};

Если массив ассоциативный (возможно, смешанный) или мы не знаем, есть ли в ряду индексов пустые места или нет, то пользуемся функциями list и each:

while (list($key, $val) = each($array)) {

Если надо вывести значения элементов в документ, то делаем

print ("…$val…");

Если обработать массив, обращаемся к его элементам:
$array[$key] = somefunction($val);

Почему я специально отметил возможность разрывов в скалярных индексах? Те, кто работал с массивами, например, в Паскале, знают — там массивы объявляются "от сих до сих, проверю, пасть порву". В отличие от Паскаля, в php массивы ничем не ограничены, мы вольны создавать массивы хоть с сотого элемента, предыдущих девяносто девяти просто не будет существовать (соответственно, sizeof такого массива будет 1). В любой момент можно создать новый элемент или удалить существующий (ну, если его не будет, программа ругаться не станет). Поэтому если при отладке программы вы не уверены, что в массиве лежит, сделайте следующее:

while (list($k, $v)=each($array))
print ("$k -- $v<br>");

Среди прочих функций, работающих с массивами, хочется отметить функции array_diff (сравнение массивов), array_rand (получение случайных элементов массива), array_unique (удаление повторов элементов) и in_array (проверка, есть ли заданное значение в массиве).
Что такое array pointer

Как вы видели, функции each и list работают без указания индекса. Естественно, что программа знает, с каким элементом она работает. Указатель, где в массиве программа "находится" в данный момент называется array pointer. Он ни в какой переменной не хранится, никак его получить нельзя (можно получить индекс элемента, на котором стоит поинтер). Но при необходимости поинтер можно двигать на начало, в конец массива, на следующий, предыдущий элемент. Впрочем, используются эти функции редко. Но на всякий случай после обращений к элементам массива и пред работой с функциями, использующими поинтер, выполняйте команду reset($array), чтобы он встал в начало массива.
Многомерность массивов

одномерный массивОпять же, здесь интерпретируемая программа куда более гибка, чем компилируемые. Как мы уже знаем, array — это такой тип данных. Как мы тоже знаем, элемент массива может классический двухмерный массив иметь любой тип данных. Значит, любой элемент массива может иметь тип данных array и быть массивом сам по себе — скалярным или ассоциативным (тогда, как соседи могут быть числами, текстом, чем угодно). В этом вложенном массиве можно создать сколько угодно элементов, и они тоже могут быть массивами. Таким образом многомерность массивов в php реализована не как многомерность, а как древовидная структура. Если вложенные в основной (корневой) массив массивы имеют одинаковый размер, получается "классический" двухмерный массив.

Это была теория многомерности. Теперь практика.

$array[$key] — имеет тип данных массив с элементом типа array"массив". И к этой переменной применимы все описанные функции. Даже чтобы превратить эту переменную в массив, можно использовать функцию array:

$array[$key] = array($val1, $val2, $val3);

Чтобы создать "классический" двухмерный массив, надо использовать вложенные функции array (за примеров — в руководстве по php).

print (sizeof($array[$key]);

Выдаст размер именно массива $array[$key], а не вложенных в двухмерный массив в php него массивов или $array. То же самое и с list & each. Отсутствие индекса при создании новых элементов так же применимо:

$array[$key][] = $val1;
$array[$key][] = $val2;
$array[$key][] = $val3;

В общем, все как с обычным массивом.