Главное меню

Использование циклов

Поскольку в ассоциативных массивах индексы не являются числами, для работы с такими массивами невозможно воспользоваться простым счетчиком в цикле for. В этом случае потребуется применять цикл foreach либо конструкции list() и each ().

При работе с ассоциативными массивами структура цикла foreach претерпевает незначительные изменения. Данный цикл можно использовать в точности так, как и в предыдущем примере, либо можно задействовать ключи:

foreach ($prices as $key => $value) {

echo $key." - ".$value."<br/>";

}

Приведенный ниже код выводит содержимое массива $prices с использованием конструкции each ():

while ($element. = each($prices)) {

echo $element ['key'];

echo " - ";

echo $element ['value'];

echo "<br />";

}

Вывод, генерируемый этим фрагментом кода, показан на рис. 3.2.

Использование циклов

Ранее были рассмотрены циклы while и оператор echo. В приведенном выше примере кода используется функция each (), которая ранее не встречалась. Эта функция возвращает текущий элемент массива и делает текущим следующий элемент. Поскольку функция each () вызывается внутри цикла while, она по очереди возвращает каждый из элементов массива и прекращает свое выполнение по достижении конца массива.

В этом примере кода переменная $element является массивом. При вызове функции each () она возвращает массив с тремя значениями и тремя индексами ячеек массива. Ячейки key и 0 содержат ключ текущего элемента, а ячейки value и 1 — значение текущего элемента. Хотя не играет роли, какую из них выбрать, предпочтительнее пользоваться именованными ячейками, а не нумерованными.

Это же можно сделать более изящным и привычным способом — воспользоваться конструкцией list () для разбиения массива на набор значений. Два значения, передаваемые функцией each (), можно разделить следующим образом:

while (list($product, $price) = each($prices)) {

echo "$product - $price<br />";

}

В этом фрагменте кода с помощью функции each () выбирается в виде массива текущий элемент массива $prices, после чего текущим становится следующий элемент. Кроме того, функция list () используется для преобразования элементов 0 и 1 массива, возвращаемого функцией each (), в две новых переменных с именами $ргоduct и $price.

Можно циклически просмотреть весь массив $prices, отображая его содержимое на экране, с помощью следующего короткого кода:

while (list($product, $price) = each($prices)) {

echo "$product - $price<br />" ;

}

При этом получается вывод, аналогичный сгенерированному предыдущим сценарием, однако этот код легче читать, так как функция list () позволяет присваивать имена переменным.

При использовании функции each () следует помнить, что массив отслеживает текущий элемент. Если в одном и том же сценарии нам необходимо воспользоваться одним и тем же массивом дважды, потребуется с помощью функции reset () снова установить текущий элемент на начало массива. Чтобы вновь выполнить циклический просмотр массива $prices, следует воспользоваться показанным ниже кодом:

reset($prices);

while (list($product, $price) = each($prices)) {

echo "$product - $price<br />";

}

В результате текущий элемент будет снова установлен на начало массива, что позволит еще раз выполнить просмотр массива.

Операции для работы с массивами

Существует набор специальных операций, применимых только в отношении массивов. Большинство из них имеет скалярные аналоги, как можно видеть в табл. 3.1.

Операции для работы с массивами

Большинство операций достаточно очевидны, и только объединение требует некоторых пояснений. Операция объединения пытается добавить элементы массива в конец массива . Если ключи элементов в совпадают с ключами некоторых элементов в , такие элементы не добавляются. Таким образом, элементы массива не перезаписываются.

Несложно заметить, что операции для работы с массивами, перечисленные в табл. 3.1, имеют аналоги среди операций, предназначенных для работы со скалярными переменными. До тех пор, пока вы помните, что операция + выполняет сложение скалярных типов данных и объединение массивов (даже если вы не интересуетесь арифметикой множеств, которая лежит в основе объединения), поведение операции не должно вызывать вопросов. Сравнивать массивы с данными скалярных типов нельзя.

Многомерные массивы

Массив не обязательно должен быть простым списком ключей и значений – каждая ячейка массива может содержать другой массив. Таким образом, допускается создание двумерных массивов. Двумерный массив можно представить себе в виде матрицы, или таблицы, обладающей шириной и высотой, иначе говоря, строками и столбцами.

Если бы для каждого товара, поставляемого компанией “Автозапчасти от Вована”, требовалось хранить более одной порции, то в этом случае мы могли бы воспользоваться двумерным массивом.

На рис. 3.3 товары, поставляемые компанией “Автозапчасти от Вована”, представлены в виде двумерного массива, каждая строка которого представляет отдельный вид товара, а каждый столбец – атрибут хранящегося товара.

Многомерные массивы

Для записи данных в массив, представленный на рис. 3.3, может послужить следующий РНР-код:

$products = array( array! 'TIR', 'Покрышки', 100 ),

array! 'OIL', 'Масло', 10 ),

array! 'SPK', 'Свечи зажигания', 4 ) );

Из этого определения видно, что теперь массив $products содержит три массива.

Вспомните, что для доступа к данным в одномерном массиве необходимо указать имя массива и индекс элемента. То же самое справедливо и в отношении двумерного массива, за исключением того, что каждый элемент теперь имеет два индекса – по строке и по столбцу. (Верхняя строка является строкой с номером 0, а крайний слева столбец – столбцом с номером 0.)

Для отображения содержимого этого массива можно было бы вручную обратиться к каждому из элементов в следующем порядке:

echo '|'.$products[0][0].'|'.$products[0][1].'|'.$products[0][2].'|<br />';

echo '|'.$products[1][0].'|'.$products[1][1].'|'.$products[1][2].'|<br />';

echo '|'.$products[2][0].'Г.$products[2][1].'|'.$products[2][2].'|<br />';

С другой стороны, для получения тех же результатов можно поместить цикл for внутрь другого цикла for:

for ($row = 0; $row < 3; $row++) {

for ($column = 0; $column < 3; $column++) {

echo '|'.$products[$row][$column];

}

echo '|<br />';

}

Обе версии кода создают в окне браузера одинаковый вывод:

|TIR| Покрышки |100|
|OIL| Масло |10|
|SPK| Свечи зажигания |4|

Единственное различие между двумя приведенными примерами состоит в том, что при использовании второй версии применительно к крупному массиву код будет намного короче. Возможно, вместо номеров столбцов вы предпочтете создать их имена, как показано на рис.3.3. Для сохранения этого же набора товаров при использовании имен столбцов, как показано на рис. 3.3, применяется следующий код:

$products = array( array( 'Code' => 'TIR',

'Description' => 'Покрышки',

'Price' => 100

),

array( 'Code' => 'OIL',

'Description' => 'Масло',

'Price' => 10

),

array( 'Code' => 'SPK',

'Description' -> 'Свечи зажигания',

'Price' => 4

)

);

Такой массив удобнее для извлечения отдельных значений. Проще запомнить, что описание хранится в столбце Description (Описание), нежели если оно хранится в столбце с номером 1. При использовании описательных индексов не приходится запоминать, что элемент хранится в ячейке [х] [у]. Данные можно легко найти, обратившись к ячейке с содержательными именами строки и столбца.

Однако при этом теряется возможность применения простого цикла for для последовательного просмотра всех столбцов. Ниже показан один из вариантов кода для отображения этого массива:

for ($row = 0; $row < 3; $row++) {

echo ' | ' . $products [$row] ['Code'] .

' | ' . $products [$row] ['Description'] .

' | ' . $products [$row] ['Price'] . '|<br />';

}

С помощью цикла for можно просмотреть внешний численно-индексированный массив $products. Каждая строка массива $products представляет собой массив с описательными индексами. Используя функции each() и list() в цикле while, можно просмотреть эти внутренние массивы. Следовательно, внутри цикла for требуется цикл while.

for ($row = 0; $row < 3; $row++) {

while (list($key, $value) = each ($products[$row])) {

echo "|$value";

}

echo '|<br />';

}

Не обязательно ограничиваться двумя измерениями – так же, как элементы массива могут содержать другие массивы, эти массивы, в свою очередь, могут содержать дополнительные массивы.

Трехмерный массив характеризуется высотой, шириной и глубиной. Если вам удобно представлять двумерный массив в виде таблицы, имеющей строки и столбцы, представьте себе стопку таких таблиц. Ссылка на каждый элемент такого массива будет осуществляться по его слою, строке и столбцу.

Если бы Вован разделил поставляемые им товары на категории, для их хранения можно было бы воспользоваться трехмерным массивом. На рис.3.4 показаны данные о товарах, поставляемых компанией “Автозапчасти от Вована”, в виде трехмерного массива.

Многомерные массивы

Из кода, который определяет этот массив, видно, что трехмерный массив представляет собой массив, содержащий массив массивов:

$categpries = array( array( array( 'CAR_TIR', 'Покрышки', 100 ),

array( 'CAR_OIL', 'Масло', 10),

array( 'CAR_SPK', 'Свечи зажигания', 4)

),

array( array( 'VAN_TIR', 'Покрышки', 120 ),

array( 'VAN_OIL', 'Масло', 12),

array( 'VAN_SPK', 'Свечи зажигания', 5)

),

array( array( 'TRK_TIR', 'Покрышки', 150 ),

array( 'TRK_OIL', 'Масло', 15),

array( 'TRK_SPK', 'Свечи зажигания', 6)

)

);

Поскольку этот массив имеет только числовые индексы, для отображения его содержимого можно воспользоваться вложенными циклами for:

for ($layer = 0; $layer < 3; $layer++) {

echo "Слой $layer<br />";

for ($row = 0; $row < 3; $row++) {

for ($column = 0; $column < 3; $column++) {

echo ' | ' . $categories[$layer] [$row] [$column];

}

echo "|<br />";

}

}

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