php перебор массива циклом for
Сравнение производительности перебора массивов в цикле через for() и foreach()
Я хотел бы обратить внимание на одну не очевидную особенность php.
Допустим у нас есть массив с целочисленными индексами
Этот массив можно перебрать в цикле двумя способами
и
Кажется вполне очевидным, что второй способ должен быть, если и не быстрее, то уж точно не медленнее.
Давайте разберемся.
— Нет. Никаких бенчмарков. Только код!
Итак, почему так происходит
Давайте посмотрим на внутренне устройство массива в php.
Внутренне, в ядре Zend, массив представлен несколькими взаимосвязанными структурами:
Структура Bucket описывает «указатель» на текущую позицию массива
Структура HashTable — это и есть сам массив во внутреннем представлении:
Даже представленной уже информации достаточно, что бы понять причину. Массивы реализованы в виде двусвязных списков.
Двусвязные списки позволяют осуществлять быструю вставку, достаточно быстрый перебор, но произвольный доступ в них — медленная операция.
Давайте посмотрим как, все-таки, Zend осуществляет итерацию элементов массива
Здесь, я думаю, все понятно без дополнительных объяснений — указатель на текущий элемент заменяется указателем на следующий элемент, ссылка на который хранится в текущем.
Теперь посмотрим как осуществляется доступ по индексу.
Здесь нужны некоторые пояснения.
Я не хотел бы утомлять читателей излишне подробным описанием того, как устроен массив arBuckets ( C массив из HashPosition — указателей на Bucket ).
Скажу только, что здесь осуществляется последовательный перебор части внутренней хэш таблицы arBuckets до поиска нужного значения.
Выводы
Достаточно быстро перебирает все элементы массива, получая их один за другим. Сложность этой операции O(n).
На каждой итерации ищет индекс во внутренней хэш таблице.
Оценочно, сложность последней операции выражалась бы суммой арифметической прогрессии n*(n+1)/2 т.е. и имела бы порядок O(n 2 ), если бы при поиске значения по индексу перебиралась бы вся хэш таблица. На самом деле, перебираются не все значения, а только часть их, поэтому сложность будет варьироваться от O(n) до O(n 2 ). И для больших массивов, она будет ближе к, O(n). Но даже в этом случае, перебор массива с доступом по ключу — более ресурсоемкая операция.
Что касается массивов со строковыми ключами (или смешанными — целочисленными и строковыми).
Все вышесказанное справедливо и для них с той разницей, что скорость доступа к строковому ключу в среднем в 8 (максимум в 16) раз больше чем к целочисленному
Website-create.ru
Продолжаем изучение массивов. В прошлых статьях мы уже научились объявлять массивы; разобрались: для чего они нужны и где могут использоваться; познакомились с многомерными и ассоциативными массивами. Теперь самое время поговорить о переборе элементов массива.
Зачастую бывает необходимо перебрать все элементы массива и проделать с ними какое-либо действие.
Делать это можно по-разному: при помощи циклов и без. Например, в прошлой статье мы получали все ключи ассоциативного массива, перебирали и выводили их при помощи цикла foreach. Там мы не стали останавливаться на теме перебора элементов массива при помощи цикла, потому что это достойно отдельной темы.
Сегодня, как раз, мы и поговорим о том, как можно перебирать элементы массива. Вы познакомитесь с достаточным количеством новых функций. Ну что ж, давайте начнем!
Для начала поговорим о переборе элементов массива при помощи циклов.
Для этого используются 3 вида циклов for, foreach и while.
Перебор элементов массива. Цикл for()
Для перебора элементов массива-списка, можно сделать следующее:
1. Сначала мы объявляем сам массив;
2. Далее узнаем число элементов массива и заносим это значение в переменную;
3. После объявляем цикл for, где в круглых скобках устанавливаем счетчик (объявляется переменная «i» со значением ноль, если эта переменная меньше общего числа элементов массива, то каждую итерацию значение «i» будет увеличиваться на единицу);
4. А в теле цикла уже можно прописать, что делать с каждым элементом массива. Можно, например, просто вывести их на экран.
Все вышеперечисленное иллюстрирует следующий код:
В результате его выполнения мы увидим на экране значения элементов массива, выведенные каждое с новой строки.
Цикл for и ассоциативные массивы
А вот для перебора элементов ассоциативного массива такой способ уже не подойдет по той простой причине, что индексами ассоциативного массива являются не числа, а строки.
Чтобы перебрать элементы ассоциативного массива в цикле for можно воспользоваться следующей конструкцией:
Как видите, мы объявили ассоциативный массив.
Далее в цикле for мы используем три новые функции:
reset() – устанавливает указатель на первый элемент массива;
next() – перемещает указатель на один элемент массива вперед;
key() – возвращает ключ текущего элемента массива.
А потом в теле цикла мы выводим индекс элемента массива, стрелку и значение элемента массива. Каждую пару индекс-значение выводим с новой строки.
Также вместо reset() можно использовать end(), тогда указатель будет установлен на последний элемент массива. Но в таком случае нужно и вместо next() использовать prev(), чтобы перемещать указатель не вперед, а назад.
Так мы можем перебрать элементы ассоциативного массива в обратном порядке.
Как Вы, наверное, знаете, цикл for используется далеко не только для работы с массивами.
А вот следующий цикл, который мы рассмотрим применяется как раз исключительно для работы с массивами.
Перебор элементов массива. Цикл foreach()
Цикл foreach() позволяет нам работать как с обычными массивами-списками, так и с ассоциативными.
Вот пример работы цикла для перебора элементов простого массива-списка с выводом всех значений элементов массива на экран.
В итоге на экране мы увидим все значения элементов этого массива.
Для ассоциативного массива эта конструкция останется точно такой же (за исключением, конечно, что в начале мы объявим не массив-список, а ассоциативный массив) и опять же мы увидим на экране все значения элементов массива.
А вот если мы захотим вывести на экран не только значения элементов, но и их ключи (Вы помните, что у ассоциативных массивов индексы представляют собой строковое значение), то данный цикл нужно будет немного усовершенствовать.
И в данном случае мы увидим на экране пару: ключ – значение, между которыми будет стрелка.
Перебор элементов массива. Цикл while()
Еще один цикл, который мы можем использовать для перебора всех элементов массива – это цикл while().
При этом нам помогут еще две функции, которые мы будет использовать совместно с этим циклом. Это функции list() и each().
В случае с массивами-списками мы будем использовать данный цикл — вот так:
Наверное, Вы уже догадались, что на экране мы увидим значения элементов массива.
Здесь функция each() возвращает текущий элемент массива, а после перемещает указатель.
В случае с ассоциативным массивом процедура остается прежней, если нам нужно получить только значения элементов массива. Но если мы хотим получить также и ключ каждого элемента, то код нужно будет слегка дополнить. Вот таким образом:
Вот так мы получим и ключи и значения.
Перебор элементов массива без использования циклов
Можно осуществлять перебор элементов массива и без использования циклов. Для этого мы будем использовать специальную функцию array_walk().
Эта функция работает следующим образом: она позволяет последовательно применять ко всем элементам массива отдельно созданную функцию. То есть сначала мы создаем самостоятельную функцию, а потом при помощи array_walk() применяем ее к каждому элементу массива. Причем в самостоятельно созданной функции мы можем прописать любое нужное нам действие над элементом массива.
Давайте создадим функцию, которая будет выводить ключ и значение элемента массива на экран, а потом при помощи array_walk() применим ее к каждому элементу нашего массива.
В итоге на экране мы увидим следующее.
Вот, пожалуй, и все, что я хотела Вам рассказать о переборе элементов массива.
Для того, чтобы лучше понять, как это все работает, советую каждый пример проделать самостоятельно, а возможно, и попрактиковаться со своими собственными примерами.
В следующей статье мы поговорим о добавлении и удалении элементов массива в разные его места.
Жду Ваших комментариев. Делитесь статьей с друзьями при помощи кнопок социальных сетей и подписывайтесь на обновление блога, чтобы всегда быть в курсе новых публикаций.
С Вами была Анна Котельникова. Успехов и до новых встреч!
Работа с циклами foreach, for, while в PHP
Учебник PHP
Практика
Важное
Регулярки
Работа с htaccess
Файлы, папки
Сессии и куки
Работа с БД
Практика по работе с БД в PHP
Перед чтением см. новые уроки раздела «Важное», которые появились выше.
Практика
Движок PHP
Продвинутые БД
Аутентификация
Практика
ООП и MVC
Абстрактные классы и интерфейсы
Трейты
ООП Магия
Практика
Практика: классы как набор методов
Циклы используются для того, чтобы некоторый участок кода выполнился несколько раз подряд.
Делается это с помощью циклов.
Есть три вида циклов: foreach, while и for. Давайте разберемся, как с ними работать и чем они отличаются друг от друга.
Цикл foreach
Цикл foreach используется для прохождения по всем элементам массива.
После команды foreach() должны идти фигурные скобки <>. Код, который лежит в этих скобках, называется телом цикла.
Этот код будет выполняться столько раз, сколько проходов сделает цикл. А он сделает столько проходов, сколько элементов у нашего массива.
Итак, синтаксис цикла foreach выглядит так:
Давайте решим следующую задачу: пусть дан массив $arr с пятью элементами, выведем столбец этих элементов с помощью цикла foreach.
Будем при каждом проходе цикла выводить на экран (с помощью echo) текущий элемент массива (тот, что лежит в переменной $elem), и ставить после него тег br, чтобы получался столбец элементов, а не строка:
Если вам нужны только значения ассоциативного массива и не нужны ключи, то $ключ=> можно не писать:
Цикл foreach имеет альтернативный синтаксис:
Как и в случае с конструкцией if-else, мы можем разорвать скобки PHP внутри цикла, далее написать что-то на HTML и опять открыть скобки PHP – в этом случае HTML код внутри цикла повторится столько раз, сколько проходов сделает цикл (в случае foreach – это количество элементов массива):
Цикл while
Цикл while будет выполняться до тех пор, пока верно (истинно) выражение, переданное ему параметром. Смотрите синтаксис:
Давайте выведем с помощью цикла while столбец цифр от одного до пяти.
Для этого введем переменную $i, которую будем использовать для того, чтобы остановить наш цикл.
Как мы это сделаем: перед циклом поставим ей значение 1, а внутри цикла будем при каждом проходе цикла увеличивать ее на единицу. Сначала она будет 1, потом 2, потом 3 и так далее.
Цикл for
Цикл for является альтернативой while. Он более сложен для понимания, но чаще всего его любят больше, чем while, за то, что он занимает меньше строчек.
Его синтаксис выглядит так:
PhpBuilder.ru
ваш путеводитель по веб программированию
Главное меню
Уроки по PHP
Урок 18. Способы перебора элементов массивов
При работе с массивами в языке программирования php множество задач решается с помощью перебора их элементов. Для этого используют рассмотренные в прошлых уроках циклические конструкции (for, whilе…) или конструкцию foreach, которая была специально создана для работы с массивами.
Давайте для начала рассмотрим способ перебора массива с помощью цикла whilе:
В результате работы этого скрипта мы увидим на экране следующую информацию:
Скорее всего в данном примере Вы столкнулись с несколькими незнакомыми или непонятными моментами. Поэтому давайте рассмотрим этот скрипт более детально.
Пример выполнения этой ж задачи с помощью цикла for:
Циклы удобно использовать для перебора индексных массивов, так как выполняются операции с целочисленными индексами. Эту задачу также можно решить и с помощью конструкции foreach. Всего есть 2 способа записи данной конструкции:
Чаще всего конструкцию foreach в php используют для перебора ассоциативных массивов. Рассмотрим следующий пример:
В некоторых случаях способы перебора элементов массива комбинируют. Давайте организуем перебор элементов многомерного массива:
bool print_r (mixed expression[, bool return]);
Пример использования на практике:
Рекомендуем самостоятельно поэксперементировать с данной php функцией.
Перебор массива в php
Пусть у нас имеется ассоциативный массив, ключами которого являются страны, а значениями — их столицы. Необходимо перебрать данный массив. Воспользуемся такой конструкцией:
В ассоциативных массивах есть такое понятия, как текущий элемент. Функция reset() ставит текущий элемент на первый элемент массива. Функция key() возвращает ключ, который имеет текущий элемент. Функция next() двигается к следующему элементу массива (сдвигает текущую позицию на один элемент вперед). Отсюда вытекает ещё одно свойство массива — это направленность.
Также иногда возникает необходимость перебрать элемент с конца. Пример:
Идея прямого перебора заключается в том, чтобы сразу получать и ключ, и значение. Есть старый вариант прямого перебора:
В 4 версии языка PHP была добавлена новая инструкция — foreach :
Самый простой вариант перебора. Данный способ рекомендуется использовать везде. Стоит отметить, что цикл foreach перед началом своей работы создаёт копию массива и работает уже с копией. Если мы потом выведем наш массив, то никаких изменений в нём не будет.
Для того, чтобы работать не с копией, а и исходным массивом, необходимо использовать ссылочный тип данных. Для примера: создадим список из трех числовых элементов, затем в цикле foreach возведём данные числа в квадрат. После всего этого выведем список:
Давайте теперь заставим массив измениться, поставив ссылочный оператор & :
В данной статье вы узнали различные варианты перебора массива в php.
На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.