Компьютеры Windows Интернет

Команда foreach языка php. О тонкостях работы foreach в PHP. Распаковка вложенных массивов с помощью list()

Цикл For Each... Next в VBA Excel, его синтаксис и описание отдельных компонентов. Примеры использования цикла For Each... Next.

Цикл For Each... Next в VBA Excel предназначен для выполнения блока операторов по отношению к каждому элементу из группы элементов (диапазон, массив, коллекция). Этот замечательный цикл применяется, когда неизвестно количество элементов в группе и их индексация, в противном случае, более предпочтительным считается использование .

Синтаксис цикла For Each... Next

For Each element In group [ statements ] [ Exit For ] [ statements ] Next [ element ]

В квадратных скобках указаны необязательные атрибуты цикла For Each... Next.

Компоненты цикла For Each... Next

*Если цикл For Each... Next используется в VBA Excel для прохождения элементов коллекции (объект Collection) или массива, тогда переменная element должна быть объявлена с типом данных Variant , иначе цикл работать не будет.

**Если не использовать в цикле свой код, смысл применения цикла теряется.

Примеры циклов For Each... Next

Цикл для диапазона ячеек

На активном листе рабочей книги Excel выделите диапазон ячеек и запустите на выполнение следующую процедуру:

Sub test1() Dim element As Range, a As String a = "Данные, полученные с помощью цикла For Each... Next:" For Each element In Selection a = a & vbNewLine & "Ячейка " & element.Address & _ " содержит значение: " & CStr(element.Value) Next MsgBox a End Sub

Информационное окно MsgBox выведет адреса выделенных ячеек и их содержимое, если оно есть. Если будет выбрано много ячеек, то полностью информация по всем ячейкам выведена не будет, так как максимальная длина параметра Prompt составляет примерно 1024 знака.

Цикл для коллекции листов

Скопируйте следующую процедуру VBA в книги Excel:

Sub test2() Dim element As Worksheet, a As String a = "Список листов, содержащихся в этой книге:" For Each element In Worksheets a = a & vbNewLine & element.Index _ & ") " & element.Name Next MsgBox a End Sub

Информационное окно MsgBox выведет список наименований всех листов рабочей книги Excel по порядковому номеру их ярлычков, соответствующих их индексам.

Цикл для массива

Присвоим массиву список наименований животных и в цикле For Each... Next запишем их в переменную a . Информационное окно MsgBox выведет список наименований животных из переменной a .

Sub test3() Dim element As Variant, a As String, group As Variant group = Array("бегемот", "слон", "кенгуру", "тигр", "мышь") "или можно присвоить массиву значения диапазона ячеек "рабочего листа, например, выбранного: group = Selection a = "Массив содержит следующие значения:" & vbNewLine For Each element In group a = a & vbNewLine & element Next MsgBox a End Sub

Повторим ту же процедуру VBA, но всем элементам массива в цикле For Each... Next присвоим значение «Попугай». Информационное окно MsgBox выведет список наименований животных, состоящий только из попугаев, что доказывает возможность редактирования значений элементов массива в цикле For Each... Next.

Sub test4() Dim element As Variant, a As String, group As Variant group = Array("бегемот", "слон", "кенгуру", "тигр", "мышь") "или можно присвоить массиву значения диапазона ячеек "рабочего листа, например, выделенного: group = Selection a = "Массив содержит следующие значения:" & vbNewLine For Each element In group element = "Попугай" a = a & vbNewLine & element Next MsgBox a End Sub

Этот код, как и все остальные в этой статье, тестировался в Excel 2016.

Цикл для коллекции подкаталогов и выход из цикла

В этом примере мы будем добавлять в переменную a названия подкаталогов на диске C вашего компьютера. Когда цикл дойдет до папки Program Files , он добавит в переменную a ее название и сообщение: «Хватит, дальше читать не буду! С уважением, Ваш цикл For Each... Next.».

Sub test5() Dim FSO As Object, myFolders As Object, myFolder As Object, a As String "Создаем новый FileSystemObject и присваиваем его переменной "FSO" Set FSO = CreateObject("Scripting.FileSystemObject") "Извлекаем список подкаталогов на диске "C" и присваиваем "его переменной "myFolders" Set myFolders = FSO.GetFolder("C:\") a = "Папки на диске C:" & vbNewLine "Проходим циклом по списку подкаталогов и добавляем в переменную "a" "их имена, дойдя до папки "Program Files", выходим из цикла For Each myFolder In myFolders.SubFolders a = a & vbNewLine & myFolder.Name If myFolder.Name = "Program Files" Then a = a & vbNewLine & vbNewLine & "Хватит, дальше читать не буду!" _ & vbNewLine & vbNewLine & "С уважением," & vbNewLine & _ "Ваш цикл For Each... Next." Exit For End If Next Set FSO = Nothing MsgBox a End Sub

Информационное окно MsgBox выведет список наименований подкаталогов на диске C вашего компьютера до папки Program Files включительно и сообщение цикла о прекращении своей работы.

В результате работы программы будут выведены не только наименования подкаталогов, видимых при переходе в проводнике к диску C , но и скрытые и служебные папки. Для просмотра списка всех подкаталогов на диске C , закомментируйте участок кода от If до End If включительно и запустите выполнение процедуры в редакторе VBA Excel.

Циклы do while и foreach

Цикл do. . . while

Цикл do...while в C# - это версия while с постпроверкой условия. Это значит, что условие цикла проверяется после выполнения тела цикла. Следовательно, циклы do...while удобны в тех ситуациях, когда блок операторов должен быть выполнен как минимум однажды. Ниже приведена общая форма оператора цикла do-while:

do { операторы; } while (условие);

При наличии лишь одного оператора фигурные скобки в данной форме записи необязательны. Тем не менее они зачастую используются для того, чтобы сделать конструкцию do-while более удобочитаемой и не путать ее с конструкцией цикла while. Цикл do-while выполняется до тех пор, пока условное выражение истинно. В качестве примера использования цикла do-while можно привести следующую программу, расчитывающую факториал числа:

Using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string args) { try { // Вычисляем факториал числа int i, result = 1, num = 1; Console.WriteLine("Введите число:"); i = int.Parse(Console.ReadLine()); Console.Write("\n\nФакториал {0} = ", i); do { result *= num; num++; } while (num

Цикл foreach

Цикл foreach служит для циклического обращения к элементам коллекции , представляющей собой группу объектов. В C# определено несколько видов коллекций, каждая из которых является массивом. Ниже приведена общая форма оператора цикла foreach:

foreach (тип имя_переменной_цикла in коллекция) оператор;

Здесь тип имя_переменной_цикла обозначает тип и имя переменной управления циклом, которая получает значение следующего элемента коллекции на каждом шаге выполнения цикла foreach. А коллекция обозначает циклически опрашиваемую коллекцию, которая здесь и далее представляет собой массив. Следовательно, тип переменной цикла должен соответствовать типу элемента массива. Кроме того, тип может обозначаться ключевым словом var. В этом случае компилятор определяет тип переменной цикла, исходя из типа элемента массива. Это может оказаться полезным для работы с определенного рода запросами. Но, как правило, тип указывается явным образом.

Оператор цикла foreach действует следующим образом. Когда цикл начинается, первый элемент массива выбирается и присваивается переменной цикла. На каждом последующем шаге итерации выбирается следующий элемент массива, который сохраняется в переменной цикла. Цикл завершается, когда все элементы массива окажутся выбранными.

Цикл foreach позволяет проходить по каждому элементу коллекции (объект, представляющий список других объектов). Формально для того, чтобы нечто можно было рассматривать как коллекцию, это нечто должно поддерживать интерфейс IEnumerable . Примерами коллекций могут служить массивы C#, классы коллекций из пространства имен System.Collection, а также пользовательские классы коллекций.

(PHP 4, PHP 5, PHP 7)

Конструкция foreach предоставляет простой способ перебора массивов. Foreach работает только с массивами и объектами, и будет генерировать ошибку при попытке использования с переменными других типов или неинициализированными переменными. Существует два вида синтаксиса:

foreach (array_expression as $value) statement foreach (array_expression as $key => $value) statement

Первый цикл перебирает массив, задаваемый с помощью array_expression . На каждой итерации значение текущего элемента присваивается переменной $value и внутренний указатель массива увеличивается на единицу (таким образом, на следующей итерации цикла работа будет происходить со следующим элементом).

Второй цикл будет дополнительно соотносить ключ текущего элемента с переменной $key на каждой итерации.

Замечание :

Когда оператор foreach начинает исполнение, внутренний указатель массива автоматически устанавливается на первый его элемент Это означает, что нет необходимости вызывать функцию reset() перед использованием цикла foreach .

Так как оператор foreach опирается на внутренний указатель массива, его изменение внутри цикла может привести к непредсказуемому поведению.

Для того, чтобы напрямую изменять элементы массива внутри цикла, переменной $value должен предшествовать знак &. В этом случае значение будет присвоено по ссылке .

$arr = array(1 , 2 , 3 , 4 );
foreach ($arr as & $value ) {
$value = $value * 2 ;
}
// массив $arr сейчас таков: array(2, 4, 6, 8)
unset($value ); // разорвать ссылку на последний элемент
?>

Указатель на $value возможен, только если на перебираемый массив можно ссылаться (т.е. если он является переменной). Следующий код не будет работать:

foreach (array(1 , 2 , 3 , 4 ) as & $value ) {
$value = $value * 2 ;
}
?>

Внимание

Ссылка $value на последний элемент массива остается даже после того, как оператор foreach завершил работу. Рекомендуется уничтожить ее с помощью функции unset() .

Замечание :

Оператор foreach не поддерживает возможность подавления сообщений об ошибках с помощью префикса "@".

Вы могли заметить, что следующие конструкции функционально идентичны:


reset ($arr );
while (list(, $value ) = each ($arr )) {
echo "Значение: $value
\n" ;
}

foreach ($arr as $value ) {
echo "Значение: $value
\n" ;
}
?>

Следующие конструкции также функционально идентичны:

$arr = array("one" , "two" , "three" );
reset ($arr );
while (list($key , $value ) = each ($arr )) {

\n" ;
}

foreach ($arr as $key => $value ) {
echo "Ключ: $key ; Значение: $value
\n" ;
}
?>

Вот еще несколько примеров, демонстрирующие использование оператора:

/* Пример 1: только значение */

$a = array(1 , 2 , 3 , 17 );

foreach ($a as $v ) {
echo "Текущее значение переменной \$a: $v .\n" ;
}

/* Пример 2: значение (для иллюстрации массив выводится в виде значения с ключом) */

$a = array(1 , 2 , 3 , 17 );

$i = 0 ; /* только для пояснения */

Foreach ($a as $v ) {
echo "\$a[ $i ] => $v .\n" ;
$i ++;
}

/* Пример 3: ключ и значение */

$a = array(
"one" => 1 ,
"two" => 2 ,
"three" => 3 ,
"seventeen" => 17
);

foreach ($a as $k => $v ) {
echo "\$a[ $k ] => $v .\n" ;
}

/* Пример 4: многомерные массивы */
$a = array();
$a [ 0 ][ 0 ] = "a" ;
$a [ 0 ][ 1 ] = "b" ;
$a [ 1 ][ 0 ] = "y" ;
$a [ 1 ][ 1 ] = "z" ;

foreach ($a as $v1 ) {
foreach ($v1 as $v2 ) {
echo " $v2 \n" ;
}
}

/* Пример 5: динамические массивы */

Foreach (array(1 , 2 , 3 , 4 , 5 ) as $v ) {
echo " $v \n" ;
}
?>

Распаковка вложенных массивов с помощью list()

(PHP 5 >= 5.5.0, PHP 7)

В PHP 5.5 была добавлена возможность обхода массива массивов с распаковкой вложенного массива в переменные цикла, передав list() в качестве значения.

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

foreach (массив as $элемент) {

foreach (массив as $ключ => $элемент) {

Например, при выполнении следующего фрагмента:

$menu = аrrау("pasta", "steak", "potatoes", "fish", "fries");

foreach ($menu as $item) {

print "$item
";

будет выведен следующий результат:

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

Второй вариант используется при работе с ассоциативными массивами:

$wine_inventory = array {

"merlot" => 15,

"zinfandel" => 17,

"sauvignon" => 32

foreach ($wine_inventory as $i => $item_count) {

print "$item_count bottles of $i remaining
";

В этом случае результат выглядит так:

15 bottles of merlot remaining

17 bottles of zinfandel remaining

32 bottles of sauvignon remaining

Как видно из приведенных примеров, конструкция foreach заметно упрощает работу с массивами.

Принцип работы конструкции switch отчасти напоминает if - результат, полученный при вычислении выражения, проверяется по списку потенциальных совпадений.

Это особенно удобно при проверке нескольких значений, поскольку применение switch делает программу более наглядной и компактной. Общий формат команды switch:

switch (выражение) {

case (условие):

case (условие):

Проверяемое условие указывается в круглых скобках после ключевого слова switch. Результат его вычисления последовательно сравнивается с условиями в секциях case. При обнаружении совпадения выполняется блок соответствующей секции. Если совпадение не будет обнаружено, выполняется блок необязательной секции default.

Как будет показано в следующих главах, одной из сильнейших сторон РНР является обработка пользовательского ввода. Допустим, программа отображает раскрывающийся список с несколькими вариантами и каждая строка списка соответствует некоторой команде, выполняемой в отдельной конструкции case. Реализацию очень удобно построить на использовании команды switch:

$user_input = "recipes"; // Команда,выбранная пользователем

switch ($user_input) :

case("search") :

print "Let"s perform a search!";

case("dictionary") :

print "What word would you like to look up?";

case("recipes") :

print "Here is a list of recipes...";

print "Here is the menu...";

Как видно из приведенного фрагмента, команда switch обеспечивает четкую и наглядную организацию кода. Переменная, указанная в условии switch (в данном примере - $user_input), сравнивается с условиями всех последующих секций case. Если значение, указанное в секции case, совпадает Со значением сравниваемой переменной, выполняется блок этой секции. Команда break предотвращает проверку дальнейших секций case и завершает выполнение конструкции switch. Если ни одно из проверенных условий не выполняется, активизируется необязательная секция default. Если секция default отсутствует и ни одно из условий не выполняется, команда switch просто завершается и выполнение программы продолжается со следующей команды.

Вы должны помнить, что при отсутствии в секции case команды break (см. следующий раздел) выполнение switch продолжается со следующей команды до тех пор, пока не встретится команда break или не будет достигнут конец конструкции switch. Следующий пример демонстрирует последствия отсутствия забытой команды break: $value = 0.4;

switch($value) :

print "value is 0.4
";

print "value is 0.6
";

print "value is 0.3
";

print "You didn"t choose a value!";

Результат выглядит так:

Отсутствие команды break привело к тому, что была выполнена не только команда print в той секции, где было найдено совпадение, но и команда print в следующей секции. Затем выполнение команд конструкции switch прервалось из-за команды switch, следующей за второй командой print.

Выбор между командами switch и if практически не влияет на быстродействие про-граммы. Решение об использовании той или иной конструкции является скорее личным делом программиста.

Команда break немедленно прерывает выполнение той конструкции while, for или switch, в которой она находится. Эта команда уже упоминалась в предыдущем разделе, однако прерывание текущего цикла не исчерпывает возможностей команды break. В общем виде синтаксис break выглядит так:

Необязательный параметр n определяет количество уровней управляющих конструкций, завершаемых командой break. Например, если команда break вложена в две команды while и после break стоит цифра 2, происходит немедленный выход из обоих циклов. По умолчанию значение n равно 1; выход на один уровень может обозначаться как явным указанием 1, так и указанием команды break без параметра. Обратите внимание: команда i f не относится к числу управляющих конструкций, прерываемых командой break.

Часто нужно пройти по всем элементам массива PHP и провести какую-нибудь операцию над каждым элементом. Например, вы можете вывести каждое значение в таблицу HTML или задать каждому элементу новое значение.

В данном уроке мы рассмотрим конструкцию foreach при организации цикла по индексированным и ассоциированным массивам.

Цикл по значениям элементов

Самый простой случай использования foreach - это организация цикла по значениям в индексированном массиве. Основной синтаксис:

Foreach ($array as $value) { // Делаем что-нибудь с $value } // Здесь код выполняется после завершения цикла

Например, следующий скрипт проходит по списку режисеров в индексированном массиве и выводит имя каждого:

$directors = array("Alfred Hitchcock", "Stanley Kubrick", "Martin Scorsese", "Fritz Lang"); foreach ($directors as $director) { echo $director . "
"; }

Выше приведенный код выведет:

Alfred Hitchcock Stanley Kubrick Martin Scorsese Fritz Lang

Цикл по ключам и значениям

А что насчет ассоциированных массивов? При использовании такого типа массивов часто нужно иметь доступ к ключу каждого элемента, так же как и к его значению. Конструкция foreach имеет способ решить поставленную задачу:

Foreach ($array as $key => $value) { // Делаем что-нибудь с $key и/или с $value } // Здесь код выполняется после завершения цикла

Пример организации цикла по ассоциированному массиву с информацией о кинофильмах, выводит ключ каждого элемента и его значение в HTML списке определений:

$movie = array("title" => "Rear Window", "director" => "Alfred Hitchcock", "year" => 1954, "minutes" => 112); echo "

"; foreach ($movie as $key => $value) { echo "
$key:
"; echo "
$value
"; } echo "
";

Данный скрипт при выполнении выведет:

Title: Rear Window director: Alfred Hitchcock year: 1954 minutes: 112

Изменение значения элемента

А как обстоит дело с изменением значения элемента при проходе цикла? Вы можете попробовать такой код:

Foreach ($myArray as $value) { $value = 123; }

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

Для изменения значений массива вам нужна ссылка на значение. Для этого нужно поставить знак & перед переменной значения в конструкции foreach:

Foreach ($myArray as &$value) { $value = 123; }

Например, следующий скрипт проходит циклом каждый элемент (имя режиссера) в массиве $directors , и использует функцию PHP explode() и конструкцию list для перемены мест имени и фамилии:

$directors = array("Alfred Hitchcock", "Stanley Kubrick", "Martin Scorsese", "Fritz Lang"); // Изменяем формат имени для каждого элемента foreach ($directors as &$director) { list($firstName, $lastName) = explode(" ", $director); $director = "$lastName, $firstName"; } unset($director); // Выводим конечный результат foreach ($directors as $director) { echo $director . "
"; }

Скрипт выведет:

Hitchcock, Alfred Kubrick, Stanley Scorsese, Martin Lang, Fritz

Отметим, что скрипт вызывает функцию unset() для удаления переменной $director после завершения первого цикла. Это хорошая практика, если вы планируете использовать переменную позже в скрипте в другом контексте.

Если не удалять ссылку, то есть риск при дальнейшем выполнении кода случайной ссылки на последний элемент в массиве ("Lang, Fritz"), если далее использовать переменную $director , что приведет к непредвиденным последствиям!

Резюме

В данном уроке мы рассмотрели, как использовать конструкцию PHP foreach для организации цикла по элементам массива. Были рассмотрены вопросы:

  • Как организовать цикл по элементам массива
  • Как получить доступ к ключу и значению каждого элемента
  • Как использовать ссылку для изменения значений при проходе цикла