Перейти к содержимому

Как выйти из цикла foreach c

  • автор:

Операторы итерации — for , foreach , do и while

Операторы итерации многократно выполняют инструкцию или блок инструкций. Оператор for выполняет текст, пока указанное логическое выражение вычисляется true . Инструкция foreach перечисляет элементы коллекции и выполняет его текст для каждого элемента коллекции. Оператор do условно выполняет свой текст один или несколько раз. Оператор while условно выполняет его тело ноль или более раз.

В любой момент в тексте инструкции итерации можно выйти из цикла с помощью инструкции break . Вы можете перейти к следующей итерации в цикле с помощью инструкции continue .

Инструкция for

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

for (int i = 0; i < 3; i++) < Console.Write(i); >// Output: // 012 

В предыдущем примере показаны элементы оператора for :

    Раздел инициализатора, который выполняется только один раз перед входом в цикл. Как правило, в этом разделе объявляется и инициализируется локальная переменная цикла. Доступ к объявленной переменной извне оператора for невозможен. В разделе инициализатора в предыдущем примере объявляется и инициализируется целочисленная переменная-счетчик:

int i = 0 

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

  • префиксное или постфиксное выражение приращения, такое как ++i или i++
  • префиксное или постфиксное выражение декремента, такое как —i или i—
  • присваивание
  • вызов метода
  • Выражение await
  • создание объекта с помощью new оператора

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

int i; int j = 3; for (i = 0, Console.WriteLine($"Start: i=, j="); i < j; i++, j--, Console.WriteLine($"Step: i=, j=")) < //. >// Output: // Start: i=0, j=3 // Step: i=1, j=2 // Step: i=2, j=1 

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

Инструкция foreach

Оператор foreach выполняет оператор или блок операторов для каждого элемента в экземпляре типа, который реализует интерфейс System.Collections.IEnumerable или System.Collections.Generic.IEnumerable , как показано в следующем примере.

List fibNumbers = [0, 1, 1, 2, 3, 5, 8, 13]; foreach (int element in fibNumbers) < Console.Write($""); > // Output: // 0 1 1 2 3 5 8 13 

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

  • Тип имеет открытый метод без параметров GetEnumerator . Этот GetEnumerator метод может быть методом расширения типа.
  • тип возвращаемого значения метода GetEnumerator должен содержать открытое свойство Current и открытый метод MoveNext без параметров с типом возвращаемого значения bool .

В следующем примере показано использование оператора foreach с экземпляром типа System.Span , который не реализует интерфейс:

Span numbers = [3, 14, 15, 92, 6]; foreach (int number in numbers) < Console.Write($""); > // Output: // 3 14 15 92 6 

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

Span storage = stackalloc int[10]; int num = 0; foreach (ref int item in storage) < item = num++; >foreach (ref readonly var item in storage) < Console.Write($""); > // Output: // 0 1 2 3 4 5 6 7 8 9 

Если исходная коллекция инструкции foreach пуста, тело оператора foreach не выполняется и пропускается. Если оператор foreach применяется к null , возникает исключение NullReferenceException.

await foreach

await foreach (var item in GenerateSequenceAsync())

Оператор await foreach можно также использовать с экземпляром любого типа, который удовлетворяет следующим условиям:

  • Тип имеет открытый метод без параметров GetAsyncEnumerator . Этот метод может быть методом расширения типа.
  • Тип возвращаемого значения метода GetAsyncEnumerator имеет открытое свойство Current и открытый метод без параметров MoveNextAsync , тип возвращаемого значения которого — Task , ValueTask или любой другой подтверждающий ожидание тип, метод ожидания которого GetResult возвращает значение bool .

Элементы потока по умолчанию обрабатываются в захваченном контексте. Чтобы отключить захват контекста, используйте метод расширения TaskAsyncEnumerableExtensions.ConfigureAwait. Дополнительные сведения о контекстах синхронизации и захвате текущего контекста см. в статье Использование асинхронного шаблона, основанного на задачах. Дополнительные сведения об асинхронных потоках см. в руководстве по асинхронным потокам.

Тип переменной итерации

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

foreach (var item in collection)

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

Можно также явно указать тип переменной итерации, как показано в следующем коде:

IEnumerable collection = new T[5]; foreach (V item in collection)

В предыдущей форме тип T элемента коллекции должен быть неявно или явно преобразован в тип V переменной итерации. Если явное преобразование из T в V завершается ошибкой во время выполнения, оператор foreach выдает исключение InvalidCastException. Например, если T является незапечатанным типом класса, V может быть любым типом интерфейса, даже тем, который T не реализует. Во время выполнения тип элемента коллекции может быть производным от T и фактически реализовать V . В противном случае возникает InvalidCastException.

Инструкция do

Оператор do выполняет оператор или блок операторов, пока определенное логическое выражение равно значению true . Так как это выражение оценивается после каждого выполнения цикла, цикл do выполняется один или несколько раз. Цикл do отличается от while цикла, который выполняется нулевым или более раз.

В следующем примере показано применение оператора do .

int n = 0; do < Console.Write(n); n++; >while (n < 5); // Output: // 01234 

Инструкция while

Оператор while выполняет оператор или блок операторов, пока определенное логическое выражение равно значению true . Так как это выражение оценивается перед каждым выполнением цикла, цикл while выполняется ноль или несколько раз. Цикл while отличается от do цикла, который выполняется один или несколько раз.

В следующем примере показано применение оператора while .

int n = 0; while (n < 5) < Console.Write(n); n++; >// Output: // 01234 

Спецификация языка C#

Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:

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

  • Асинхронные потоки
  • Поддержка расширения GetEnumerator для циклов foreach

См. также

Совместная работа с нами на GitHub

Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.

Прервать цикл forEach (javascript)

Есть массив со значениями. Внутри цикла есть условие поиска значения массива. Задача: остановить дальнейший перебор цикла при первом найденном значении. Спасибо за помощь. Решение: (спасибо Lieutenant Jim Dangle)

[1, 2, 3, 4, 3].some(function(el,i) < if (el == 3) < console.log(i); return el; >>); 

Отслеживать
Менеджер Типографии
задан 6 янв 2017 в 12:28
Менеджер Типографии Менеджер Типографии
587 2 2 золотых знака 5 5 серебряных знаков 18 18 бронзовых знаков
@LieutenantJimDangle, твой код так же не работает как и код в вопросе 🙂
6 янв 2017 в 12:40
@LieutenantJimDangle, это просто убирает синтаксическую ошибку
6 янв 2017 в 12:43
Добавь в вопрос пример твоего массива, и что именно в нем ты хочешь найти и вывести.
6 янв 2017 в 12:59

Код решения неверен. результат возвращаемый функцией Callback переданной в some нужен только для проверки останавливать ли проход по коллекции или нет. Поэтому если вдруг искомый элемент будет 0 - то в твоем случае some пройдет по всей коллекции

6 янв 2017 в 13:09

4 ответа 4

Сортировка: Сброс на вариант по умолчанию

метод forEach не предусматривает возможности прервать обход коллекции.

Если нужно проверить наличие конкретного элемента удовлетворяющего условию, лучше использовать метод some

var massiv = ['2', '1', '3']; console.log(massiv.some(function(item) < console.log('some', item); return (item == "1"); >));

Если проверяются полностью объекты, можно использовать метод indexOf

var massiv = ['2', '1', '3']; console.log(massiv.indexOf("1"));

Если нужно найти индекс элемента удовлетворяющего условию, то подойдет метод findIndex

var massiv = ['2', '1', '3']; console.log(massiv.findIndex(function(item) < console.log('findIndex', item); return item == "1"; >));

Если очень хочется использовать именно forEach - можно поместить его в try..catch и кидать ошибку если элемент найден.

var massiv = ['2', '1', '3']; try < massiv.forEach(function(item, i) < console.log('foreach', i); if (item == "1") < throw < reason: "finded", index: i >> >); > catch (< reason, index >) < if (reason) < console.log(reason, ':', index) >>

Вместо встроенных функций массива, можно также воспользоваться циклом for . В этом случае для прерывания цикла можно использовать выражение break

Отслеживать
ответ дан 6 янв 2017 в 12:48
81k 9 9 золотых знаков 78 78 серебряных знаков 135 135 бронзовых знаков

Во всех варианта у Вас именно поиск конкретного элемента. А задача была найти первый найденный. В Вашей интерпритации массива было бы так: var massiv = ['2', '1', '3', '1']; И нужно найти индекс первой найденной еденички (то есть результатом остановки было бы значение 1 (второй элемент массива)

6 янв 2017 в 12:54

@МенеджерТипографии, все методы some , findIndex - прекращают выполнение, как только callback вернет true . Метод indexOf , находит первое вхождение элемента. начиная с указанного индекса, так как индекс не указан, проверка начинается с первого элемента массива.

6 янв 2017 в 12:56

@МенеджерТипографии, если задача заключается просто в проверке наличия элементов в массиве. то foreach вообще не нужен. В противном случае, все методы делают то же самое что и код в вопросе, за исключением прекращения выполнения когда условие выполнилось

6 янв 2017 в 12:58

В методе forEach не предусмотренa остановка как в лупе посредством брейк.

Использовать every заместо forEach . Когда будет false , все остановится.

Это самый правильный способ.

massiv.every(function(item, i) < if (item == "1") < console.log(i); return false; >else < return true; >>); 

Отслеживать
81k 9 9 золотых знаков 78 78 серебряных знаков 135 135 бронзовых знаков
ответ дан 6 янв 2017 в 12:32
3,416 1 1 золотой знак 10 10 серебряных знаков 18 18 бронзовых знаков
на счет Это самый правильный способ - можно поспорить
6 янв 2017 в 13:04

я привел пример точно на поставленый вопрос, это делает то, что надо @Менеджер Типографии, все остальные ответы, по моему мнению не еффктивны. есть четко поставленый вопрос, и есть решение.

6 янв 2017 в 13:23

some - делает абсолютно то же самое. разница только в знаке сравнения. И все это менее эффективно чем обычный for за счет постоянного вызова функции-коллбэка. Кроме того, неизвестно что вообще нужно автору, что именно он хочет делать с полученным элементом. нужен ли ему элемент или индекс элемента и т.д.

Как можно выйти из цикла foreach js

В JavaScript цикл forEach не имеет стандартного способа выйти из него до его завершения. Как уже упоминалось, оператор break не работает в цикле forEach . Однако, можно использовать исключения (throw) для выхода из цикла.

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

const array = [1, 2, 3, 4, 5]; let isValueFound = false; try  array.forEach(function (element)  if (element === 3)  isValueFound = true; throw new Error('Value found'); > >); > catch (e)  if (e.message !== 'Value found')  throw e; > > if (isValueFound)  console.log('Value is found'); > else  console.log('Value is not found'); > 

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

Цикл foreach и инструкции break/continue в PHP

Без цикла foreach не обходится ни один сайт. Разберёмся как его использовать и можно ли прерывать или пропускать итерации цикла.

Цикл foreach

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

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

один два три

Разберём по порядку, что же произошло. Внутри скобок foreach написано $a as $b, что означает: "бери по порядку элементы массива $a и помещай их значение в $b". Что программа и делает: берёт первый элемент массива $a со значением 'один' и задаёт это значение переменной $b. А в теле цикла идёт вывод значения "echo $b;". Как только все команды из тела цикла выполнены, начинается вторая итерация: берётся второй элемент из массива $a со значением 'два'. Производится то же самое действие. И так далее, пока в массиве не останется элементов.

Давайте усложним задачу и представим, что у массива есть ключи и их тоже надо передавать. А чтобы было не скучно, сделаем ключи текстовыми:

 'один', 'two' => 'два', 'three' => 'три' ); foreach( $a as $b => $с )< echo $b; echo ' = '; echo $c; echo '
'; > ?>

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

one = один two = два three = три

Как можно видеть из примера, цикл отличается выражением в скобках $a as $b => $с. Это выражение означает "бери по порядку элементы массива $a и помещай их значение в $с, а ключи элементов в переменную $b".

Обратите внимание, что если внутри цикла изменить значение переменных $b или , то значение переменной $a не поменяется.

Чтобы изменить значение элемента массива $a, можно использовать внутри цикла foreach конструкцию $a[$b] = 'новое_значение'. Тогда в массиве $a, в элементе с ключом $b, изменится значение на 'новое_значение'

Прерывание цикла (break)

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

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

один два

Слово 'три' не будет напечатано, потому что в коде перед ним сработает инструкция break и цикл завершится.

Следующая итерация цикла (continue)

Иногда нужно не завершать цикл, а перейти к следующей итерации, к следующему элементу. Для этого используется инструкция continue:

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

один три

На элементе со значением 'два' сработает инструкция continue и последующие команды не будут выполнены. А вместо этого цикл начнётся заново, взяв следующий элемент массива $a.

Инструкции break и continue работают не только в циклах foreach, но и в циклах while и for.

Обратите внимание, что инструкции break и continue воздействуют только на родительский цикл, в котором находятся. Если несколько циклов вложено один в другой, а инструкция стоит внутри второго, то она никак не повлияет на первый цикл.

Пример из реального проекта

Приведём пример цикла, который приближен к циклу из реального проекта. Этот цикл будет находиться на странице со списком новостей и будет выводить название новости и короткое описание. Сам цикл будет проходить внутри массива, который описывает всю страницу. Именно таким способом программируются современные сайты: в начале ".php" файла вы загружаете данные из базы данных и собираете их большой-большой массив, обрабатываете и подготавливаете для вывода. А во второй части файла вы выводите значение элементов массива вперемешку с HTML кодом, но ничего не считаете и не обращаетесь к базе:

 'Название первой новости', 'text' => 'Текст первой новости', ); $arResult['items'][] = array( 'name' => 'Название второй новости', 'text' => 'Текст второй новости', ); ?>      ?>  

В результате вызова этой страницы, в окне браузера мы увидим:

Название первой новости Текст первой новости Название второй новости Текст второй новости

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *