Профессиональная разработка Web-приложений.  
Боишься нашего дизайна?
Новости
PDF журнал
Участники проектa
Сотрудничество
Ссылки
Карта сайта
Комментарии
Комментарии к статье
Добавить комментарий
Обсудить на форуме
Информация об авторе
Оценка статьи

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

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

Для тех, кому интересно "глубинное" описание принципов работы массиовов в 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;
В общем, все как с обычным массивом.






For comment register here
   Unknown 2001-01-21 15:12
Разницы между ассоциативными и обчными массивами нет. Это одно и то же. Второе: есть count, зачем sizeof?

   Unknown 2001-01-21 16:05
Кто говорит, что есть разница?

   2001-02-21 12:25
Господин, а почему используем each(...)? Почему бы про foreach(...) не написать? Гораздо удобнее использовать его вместо each. А в остальном ХОРОШАЯ статья.
Успехов вам.

   Unknown 2001-02-21 13:18
По-моему, foreach не поддерживатся... А в остальном - спасибо :)

   2001-03-30 14:45
Есть вопросик. Как обнулить все элементы массива ... есть какая-нить хитрость ?
Или нужно что-то типа for ($i=0;$i<sizeof($array);$i++) ;

   Unknown 2001-03-30 15:38
Только так.

   Unknown 2001-04-09 13:55
статья крайне поверхностная, как же устроены на самом деле ассоциативные массивы? по какому принципу ключу находится в соответствие значение? обычный список (голова|хвост) как в lisp'e, прологе и пр.? как происходит выделение памяти? какая разница в скорости по сравнению, например, с перлом?

   Unknown 2001-04-09 14:48
Ассоциативные массивы устроены точно так же, как и обычные скалярные. Сравнивать с Перлом трудно, т.к. всё зависит от размеров задачи.

   Unknown 2001-04-21 07:46
for ($i=$m;$i<sizeof($array)+$m;$i++)
имхо тут "+$m" не нужно. зачем оно?

   Unknown 2001-04-21 08:39
Да, действительно, всё можно уменьшить на $m. :)

   Unknown 2001-05-08 14:45
а почему нельзя просто print_r($array) ?

   2001-07-02 17:49
Спасибо за толковую статью.
Если не затруднит, напишите, как отсортировать двумерный массив по, например, элементам верхней иерархии. То есть если есть массив (яблоки(красные, спелые, июньские), смородина (белая, не спелая, июльская), малина (желтая, спелая, сентябрьская)), отсортировать по цвету :)

   Unknown 2001-07-02 18:42
В мануале описана функция, сортирующая многомерные массивы.

   2001-10-29 11:44
А как "развернуть" многомерный массив, ну например, в обычный список, если заранее не известно количество его измерений?

   Unknown 2001-10-29 12:37
Пройтись по всем элементам чем-то вроде рекурсивной функции: если элемент имеет обычный тип данных, тогда скинуть в итоговый массив, если тип данных - массив, пройтись циклом по нему.

   2003-07-30 16:19
/*************/
for ($i=0;$i<sizeof($array);$i++)
/*************/
Вас кто учил циклы писать?
sizeof() будет вызваться кадый раз при проходе цикла. Нахер это?
$count = count($array);
for ($i=0;$i<$count;$i++){
//попTрли
}

   2003-12-09 12:34
"А как развернуть многомерный массив, ну например, в обычный список, если заранее не известно количество его измерений?"
Ответ: самый простой способ:
print_r(array_values($array)); вывести на экран весь массив

можно ещё в дополнение print_r(array_keys($ListTask)); вывести ключи массива

   2004-11-02 13:42
насчёт как обнулить масив. можа лучше использовать
unset($array);
а затем заново создать его? так не быстрее получиться чем обнулять его циклом?

   2005-06-14 09:56
Вообще-то, если первый элемент массива у нас идет под индексом 0
$count = count($array)-1;
Иначе может возникнуть мааааленкий глюк ;-)

   2006-05-16 11:12
а ниче так статья, многое стало понятно. спасибо

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

 
 
 
    © 1997-2008 PHPClubTeam
[]