Массивы в PHP: перебор элементов и сохранение серии последовательных чисел
В этом материале разберемся с двумя задачами, касающимися работы с массивами.
Первая - совсем небольшая - сохранение в массиве ряда последовательных целых чисел.
Вторая - более обширная и часто используемая - перебор элементов массива.
Инициализация массива диапазоном целых чисел
Итак, для решения нашей первой задачи можно воспользоваться функцией range($start, $stop):
$cards = range(1, 52);
Так мы получим массив, в котором хранятся числа от 1 до 52.
Если нам нужно, чтобы числа сохранялись не подряд, то приращение мы должны задать третьим параметром для range():
$odd = range(1, 52, 2);
Как вы уже догадались, код выше позволит нам создать массив, хранящий все нечетные числа от 1 до 52: 1,3,5...51.
Для четных числе все аналогично, меняется только значение первого параметра:
$even = range(2, 52, 2);
С этим мини-вопросом разобрались. Теперь перейдем к более объемной задаче.
Перебор элементов массива
Одна из тривиальных задач при разработке веб-приложений (и не только) - работа с данными в цикле, иными словами, организация перебора элементов массива и выполнение с ними (или с частью из них) неких операций.
Отличным помощником в этом случае будет цикл foreach:
foreach ($array as $value) { // действия с переменной $value }
Для получения ключей и значений массива воспользуемся тем же циклом с немного другим синтаксисом:
foreach ($array as $key => $value) { // ... }
Другой вариант - воспользоваться циклом for:
for ($key = 0, $size = count($array); $key < $size; $key++) { // ... }
Третий способ - использование функции each() в сочетании с list() и конструкцией while:
reset($array); // Внутренний указатель устанавливается в начало массива while (list($key, $value) = each ($array)) { // ... }
Обычно цикл foreach является самым лаконичным способом перебора массива:
// foreach только со значениями элементов массива foreach ($items as $cost) { // ... } // foreach с ключами и значениями элементов массива foreach($items as $item => $cost) { // ... }
Когда PHP имеет дело с foreach, он перебирает содержимое копии массива вместо самого исходного массива. Если же мы используем each() и for, PHP работает с исходным массивом, т.е. совершает именно его перебор.
— Регулярная проверка качества ссылок по более чем 100 показателям и ежедневный пересчет показателей качества проекта.
— Все известные форматы ссылок: арендные ссылки, вечные ссылки, публикации (упоминания, мнения, отзывы, статьи, пресс-релизы).
— SeoHammer покажет, где рост или падение, а также запросы, на которые нужно обратить внимание.
SeoHammer еще предоставляет технологию Буст, она ускоряет продвижение в десятки раз, а первые результаты появляются уже в течение первых 7 дней. Зарегистрироваться и Начать продвижение
Из этого следует, что при изменении массива внутри цикла ожидаемое поведение можно и не получить. Поэтому если вам понадобится изменить массив, обращайтесь к нему напрямую:
foreach ($items as $item => $cost) { if (! in_stock($item)) { unset($items[$item]); // Обращение к массиву напрямую } }
Поскольку переменные, возвращаемые foreach(), не являются псевдонимами для исходных значений в массиве, их изменения не отражаются в массиве. Именно по этой причине изменять следует $items[$item] вместо $cost.
Следующий момент заключается в том, что при использовании 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) может привести к преждевременному завершению цикла.
Понятно, что это не очень удобно, поэтому данный синтаксис используется редко, а мы рассматриваем его только для того, чтобы было проще разобраться в старом коде PHP.
Наконец, есть еще функция array_map(), которую следует использовать для передачи каждого элемента массива некой функции для обработки:
// Преобразование всех слов к нижнему регистру $lc = array_map('strtolower', $words);
Первый параметр - это имя функции, которая, по нашей задумке, будет осуществлять изменение отдельных элементов массива. Второй же аргумент - сам массив.
В общем случае эта функция уступает перечисленным ранее методам в гибкости, но она хорошо подходит для обработки и слияния нескольких массивов.
Иногда бывают ситуации, что мы не можем быть уверены в том, что обрабатываемые данные не являются скалярным значением, поэтому необходимо защититься от возможного вызова foreach для «не массива». Воспользуемся для этого функцией is_array():
— Разгрузит мастера, специалиста или компанию;
— Позволит гибко управлять расписанием и загрузкой;
— Разошлет оповещения о новых услугах или акциях;
— Позволит принять оплату на карту/кошелек/счет;
— Позволит записываться на групповые и персональные посещения;
— Поможет получить от клиента отзывы о визите к вам;
— Включает в себя сервис чаевых.
Для новых пользователей первый месяц бесплатно. Зарегистрироваться в сервисе
if (is_array($items)) { // Код с циклом foreach для массива } else { // Код для скалярного значения }
Другой способ основан на преобразовании всех переменных в массив функцией settype():
settype($items, 'array'); // Код цикла для массивов
При таком подходе скалярное значение преобразуется в массив, состоящий из одного единственного элемента, а код становится более компактным за счет некоторого снижения эффективности.
Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!
Смотрите также: