Разработчику. Сборник рецептов PHP
Задавайте вопросы

Перебор элементов массива

Вернуться назад

Задача

Необходимо перебрать по очереди и обработать все или некоторые элементы массива.

Решение

Используйте оператор foreach:

foreach ($array as $value) {
    // Действие с $value
}

Или для получения ключей и значений массива:

foreach ($array as $key => $value) {
    // Действие II
}

Другим способом является применение оператора for:

for ($key = 0, $size = count($array); $key < $size; $key++) {
    // Действие III
}

И наконец, можно использовать функцию each() в комбинации с функцией list() и оператором while:

reset($array) // сброс внутреннего указателя в начало массива
while (list($key, $value) = each ($array)) {
    // Окончательное действие
}

Обсуждение

Цикл foreach – это наипростейший способ выполнения итераций с массивом:

// оператор foreach со значениями
foreach ($items as $cost) {
...
}

// оператор foreach с ключами и значениями
foreach($items as $item => $cost) {
...
}

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

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

reset($items);
while (list($item, $cost) = each($items)) {
    if (! in_stock($item)) {
        unset($items[$item]);         // непосредственная адресация массива
    }
}

Переменные, возвращаемые функцией each(), не ссылаются на исходные значения массива – это их копии, поэтому их изменение не отражается на массиве. Вот почему нужно модифицировать переменную $items[$item] вместо переменной $item.

При использовании функции each() PHP отслеживает и запоминает положение внутри цикла. Чтобы начать цикл сначала после выполнения первого прохода, нужно вызвать функцию reset() для того, чтобы вернуть указатель обратно в положение перед циклом. В противном случае функция each() вернет значение false.

Цикл for работает только в случае массивов с последовательными целыми ключами. Если длина массива не изменяется, то неэффективно при каждом прохождении цикла снова вызывать функцию count() для вычисления переменной $items. Поэтому для хранения длины массива всегда используйте переменную $size:

for ($item = 0, $size = count($items); $item < $size; $item++) {
    ...
}

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

for ($item = count($items) - 1; $item >= 0; $item - -) {
    ...
}

Ассоциативная версия цикла for:

for (reset($array); $key = key($array); next($array) ) {
    ...
}

Это приведет к ошибке, если какой-нибудь элемент содержит строку со значением, приравненным к false, поэтому вроде бы нормальное значение, такое как 0, может привести к досрочному завершению цикла.

Наконец, используйте функцию array_map() для передачи каждого элемента обрабатывающей функции:

// переводим все слова в нижний регистр
$lc = array_map('strtolower', $words);

Первым аргументом функции array_map() является имя функции, которая модифицирует отдельный элемент, а второй аргумент – это массив, обрабатываемый в цикле.

Как правило, эти функции считаются менее гибкими, по сравнению с ранее рассмотренными методами, но они хорошо подходят для обработки и объединения множества массивов.

Если не известно, должны ли обрабатываться данные как скалярные величины или как массив, то необходимо предотвратить использование оператора foreach с не массивом. Один из способов – это применение функции is_array():

if (is_array($items)) {
    // код с циклом foreach для массива
} else {
    // код для скалярной величины
}

Другим способом является принудительное преобразование всех переменных в массив с помощью функции settype():

settype($items, 'array');
// код цикла для массивов

Это превращает скалярное значение в одноэлементный массив и делает код более привлекательным за счет небольших дополнительных накладных расходов.

Вернуться назад

Рейтинг@Mail.ru

Яндекс.Метрика

Индекс цитирования

Рейтинг Сайтов ДОСКИ.РУ