Foreach 루프
1. 개요
Foreach 루프는 프로그래밍 언어에서 컬렉션(배열, 리스트 등)의 각 요소에 대해 반복 작업을 수행하는 제어 구조이다. 대부분의 언어에서 "for each item in collection" 형태의 문법을 사용하며, C++, C#, 자바, 자바스크립트, 펄, PHP, 파이썬, 루비 등 다양한 언어에서 지원한다. C 언어는 매크로를 통해 유사한 기능을 구현하며, C++11부터는 자바와 유사한 foreach 루프를 제공한다. 쉘 스크립트, PL/SQL 등에서도 foreach와 유사한 기능을 제공한다.
| 유형 | 제어 흐름 구문 |
|---|---|
| 하위 유형 | 반복문 |
| 다른 이름 | 강화된 for 루프 |
| 용도 | 컬렉션의 항목 순회 |
|---|
2. 문법
대부분의 프로그래밍 언어에서 `for` 키워드를 사용하며, 다음과 비슷한 형태를 가진다.
```text
for each item in collection:
do something to item
```
몇몇 언어에서는 다음과 같이 `foreach`를 사용하기도 한다.
```text
foreach(키, 값) in 컬렉션:
# 값에 대해 무엇인가 수행 #
```
Perl에서의 구문은 다음과 같다.
```text
foreach 변수 (리스트):
문
```
이 루프는 대략 다음과 같은 순서로 실행된다.
1. 변수에 리스트의 어떤 요소에 대한 참조를 대입한다.
2. 문을 실행한다.
3. 모든 요소를 참조하지 않은 경우에는 변수에 "다음 요소"를 대입하고 문 실행으로 돌아간다.
선형 리스트나 배열 등 요소의 순서가 정해져 있는 것은, 일반적으로 그 순서대로 루프가 실행되므로, 이 경우 다음과 거의 같다.
```text
for ( my $i = 0; $i < @list; $i++ ):
변수 = $list[$i];
문
```
단, 해시 테이블로 구현된 연관 배열 등, 요소의 순서 관계가 정해져 있지 않은 "컬렉션"의 경우, 그 참조되는 순서는 정해져 있지 않다.
3. 언어 지원
다양한 프로그래밍 언어에서 foreach 루프를 지원하거나 유사한 기능을 제공한다. 다음은 그 목록이다.
* ABC
* ActionScript
* Ada
* C++ (C++11부터)
* C#
* ColdFusion 마크업 언어 (CFML)
* 코브라
* D
* Daplex (쿼리 언어)
* 델파이
* ECMAScript
* Erlang
* Java (1.5부터)
* 자바스크립트
* Lua
* Objective-C (2.0부터)
* ParaSail
* Perl
* PHP
* 프롤로그
* 파이썬
* R
* REALbasic
* 레볼
* Red
* 루비
* Scala
* 스몰토크
* Swift
* Tcl
* tcsh
* 유닉스 셸
* Visual Basic (.NET)
* Windows PowerShell
C와 C++ pre-C++11은 foreach 루프를 지원하지 않는다.
3.1. C
C 언어는 자체적으로 foreach 구문을 지원하지 않지만, 매크로를 사용하여 비슷하게 구현할 수 있다.
하지만 두 가지 문제가 있다.
* 매크로는 위생적이지 않다. 즉, 루프 이후에도 기존 범위 내에서 새로운 변수를 선언하고 유지한다.
* 서로 다른 컬렉션 유형(예: 배열과 연결 리스트)에서 작동하거나 사용자 정의 유형으로 확장될 수 있는 단일 foreach 매크로는 정의할 수 없다.
C 문자열을 char의 컬렉션으로 사용하는 예시는 다음과 같다.
#include
/* 문자열을 char 값의 컬렉션으로 보는 foreach 매크로 */
#define foreach(ptrvar, strvar) \
char* ptrvar; \
for (ptrvar = strvar; (*ptrvar) != '\0'; *ptrvar++)
int main(int argc, char argv) {
char* s1 = "abcdefg";
char* s2 = "123456789";
foreach (p1, s1) {
printf("loop 1: %c\n", *p1);
}
foreach (p2, s2) {
printf("loop 2: %c\n", *p2);
}
return 0;
}
C int 배열을 int의 컬렉션으로 사용 (배열 크기는 컴파일 시점에 알려짐)하는 예시는 다음과 같다.
#include
/* int 값의 배열을 int 값의 컬렉션으로 보는 foreach 매크로 */
#define foreach(intpvar, intarr) \
int* intpvar; \
for (intpvar = intarr; intpvar < (intarr + (sizeof(intarr)/sizeof(intarr[0]))); ++intpvar)
int main(int argc, char argv) {
int a1[] = {1, 1, 2, 3, 5, 8};
int a2[] = {3, 1, 4, 1, 5, 9};
foreach (p1, a1) {
printf("loop 1: %d\n", *p1);
}
foreach (p2, a2) {
printf("loop 2: %d\n", *p2);
}
return 0;
}
문자열 또는 배열을 컬렉션으로 사용 (컬렉션 크기는 런타임에 알려짐)하는 가장 일반적인 경우는 다음과 같다.
#include
#include
/* 주어진 유형의 배열을 주어진 유형의 값 컬렉션으로 보는 foreach 매크로 */
#define arraylen(arr) (sizeof(arr)/sizeof(arr[0]))
#define foreach(idxtype, idxpvar, col, colsiz) \
idxtype* idxpvar; \
for (idxpvar = col; idxpvar < (col + colsiz); ++idxpvar)
int main(int argc, char** argv) {
char* c1 = "collection";
int c2[] = {3, 1, 4, 1, 5, 9};
double* c3;
int c3len = 4;
c3 = (double*)calloc(c3len, sizeof(double));
c3[0] = 1.2; c3[1] = 3.4; c3[2] = 5.6; c3[3] = 7.8;
foreach (char, p1, c1, strlen(c1)) {
printf("loop 1: %c\n", *p1);
}
foreach (int, p2, c2, arraylen(c2)) {
printf("loop 2: %d\n", *p2);
}
foreach (double, p3, c3, c3len) {
printf("loop 3: %.1lf\n", *p3);
}
return 0;
}
3.2. C++
C++11은 foreach 루프를 제공하며, 문법은 자바와 유사하다.
```cpp
#include
int main()
{
int myint[] = {1, 2, 3, 4, 5};
for (int i : myint)
{
std::cout << i << '\n';
}
}
```
C++11 범위 기반 for 문은 GNU 컴파일러 모음 (GCC) (버전 4.6부터), Clang (버전 3.0부터) 및 Visual C++ 2012 (버전 11)에 구현되었다.
범위 기반 `for`는 다음의 구문 설탕과 동일하다.
```cpp
for (auto __anon = begin(myint); __anon != end(myint); ++__anon)
{
auto i = *__anon;
std::cout << i << '\n';
}
```
컴파일러는 인자 의존적 탐색을 사용하여 `begin`과 `end` 함수를 해결한다.
C++ 표준 라이브러리는 또한 각 요소를 함수에 적용하는 `std::for_each`를 지원하며, 이 함수는 미리 정의된 함수 또는 람다 표현식일 수 있다. 범위 기반 for는 시작부터 끝까지의 범위만 있지만, 처음 두 매개변수를 변경하여 범위 또는 방향을 변경할 수 있다.
```cpp
#include
#include
#include
int main()
{
std::vector
std::for_each(v.begin(), v.end(), [](int i)
{
std::cout << i << '\n';
});
std::cout << "reversed but skip 2 elements:\n";
std::for_each(v.rbegin()+2, v.rend(), [](int i)
{
std::cout << i << '\n';
});
}
```
C++ 프레임워크인 Qt는 STL 반복자 인터페이스를 사용하여 foreach 루프를 제공하는 매크로를 제공한다.
```cpp
#include
#include
int main()
{
QList
list << 1 << 2 << 3 << 4 << 5;
foreach (int i, list)
{
qDebug() << i;
}
}
```
무료 동료 검토를 거친 이식 가능한 C++ 라이브러리 세트인 Boost도 foreach 루프를 제공한다.
```cpp
#include
#include
int main()
{
int myint[] = {1, 2, 3, 4, 5};
BOOST_FOREACH(int &i, myint)
{
std::cout << i << '\n';
}
}
```
C++11에서 범위 기반 for 루프가 언어 사양으로 추가되었다.
```cpp
for (형 변수 : 컬렉션) {
문
}
```
위에서 "컬렉션"이라고 표기된 부분에는 배열 외에도 `std::vector`나 `std::array`와 같은 표준 라이브러리에서 '컨테이너'로 분류되는 다양한 객체도 사용할 수 있다.
1998년 표준 규격화 당시부터 C++ 표준 라이브러리에 `for_each` 알고리즘(함수 템플릿)이 존재한다.
```cpp
함수 객체 = std::for_each(
시작 이터레이터,
마지막 이터레이터,
함수 객체
);
```
C++11에서는 C#과 마찬가지로 형 추론 및 람다 함수와 람다 표현식을 결합하여 위 구문이 위력을 발휘하게 된다.
C++/CLI 언어 및 Microsoft Visual C++ 2005 이후의 독자적인 확장 기능에서는 `for each` 문을 사용할 수 있지만, 불안정하여 정상적으로 동작하지 않는 경우가 있다. 이는 C++11의 범위 기반 for 루프와 호환되지 않는다.
```cpp
for each (변수 in 컬렉션) {
문
}
3.3. C#
C#에서는 `foreach` 문을 다음과 같이 사용할 수 있다.
```csharp
foreach (int x in myArray) { Console.WriteLine(x); }
```
위 예시에서 `myArray`는 정수 배열이다. `foreach` 문은 `myArray`의 각 요소를 순회하며 `x` 변수에 할당하고, 콘솔에 `x` 값을 출력한다.
언어 통합 쿼리(LINQ)를 사용하면 다음과 같은 구문도 가능하다.
```csharp
myArray.ToList().ForEach(x => Console.WriteLine(x));
```
이 구문은 람다식을 사용하여 `myArray`의 각 요소를 순회하며 콘솔에 출력한다.
C#의 `foreach` 문은 배열뿐만 아니라 `IEnumerable` 또는 `IEnumerable
C++/CLI 언어는 C#과 유사한 구문을 제공한다.
```csharp
for each (int x in myArray)
{
Console::WriteLine(x);
}
3.4. 자바
자바에서는 for-each 구문이 자바 개발 키트 (JDK) 1.5.0에서 도입되었다.
공식 자료에서는 이 구문에 대해 "향상된 for 루프"(Enhanced for Loop), "For-Each 루프", 그리고 "foreach 문"이라고 불린다.
```java
for (Type item : iterableCollection) {
// item에 대해 수행할 작업
}
```
자바는 또한 자바 8부터 스트림 API를 제공한다.
```java
List
intList.stream().forEach(i -> System.out.println(i));
```
Java 5에서 도입된 확장 for문(enhanced for statement)은 foreach문에 해당한다. 컬렉션에는 java.util.Collection영어 등, java.lang.Iterable영어을 구현하는 식을 배치할 수 있다.
```java
for (타입 변수 : 컬렉션) {
문장
}
```
또한 문장이 아닌 메서드이지만,
```java
컬렉션.forEach( 변수 -> {
문장
} )
```
과 같이 .forEach 메서드에 람다 함수를 전달하여 컬렉션의 요소에 대해 반복 처리를 수행할 수 있다.
3.5. 자바스크립트
자바스크립트에서 객체의 키를 순회할 때는 `for...in` 루프를 사용한다.
```javascript
for (const key in myObject) {
// myObject[key]로 작업 수행
}
```
프로토타입 체인을 통해 상속된 속성을 제외하고 객체 자체의 속성만 반복하려면 `hasOwnProperty()` (구형 브라우저) 또는 `hasOwn()` (최신 브라우저) 테스트를 추가한다.
```javascript
for (const key in myObject) {
if (myObject.hasOwnProperty(key)) { // 구형 브라우저
// myObject[key]로 작업 수행
}
if (Object.hasOwn(myObject, key)) { // 최신 브라우저
// myObject[key]로 작업 수행
}
}
```
`Object.keys()`와 `for...of` 루프를 함께 사용하면 객체 키를 더 간결하게 반복할 수 있다.
```javascript
const book = {
name: "A Christmas Carol",
author: "Charles Dickens"
};
for (const key of Object.keys(book)) {
console.log(`Key: ${key}, Value: ${book[key]}`);
}
```
`for...in` 문은 객체의 프로퍼티명을 변수에 대입하므로, 프로퍼티 값은 `객체[변수]`로 얻는다.
```javascript
for (const 변수 in 객체) {
문
}
```
`for...in` 문은 사용자 정의 프로퍼티에 대해 프로토타입 체인까지 거슬러 올라가 반복하므로, 배열에 사용 시 주의해야 한다.
```javascript
const array = new Array(3);
let output = "";
for (const key in array) { output += key + " "; }
// array.length === 3 이지만, 배열 요소가 정의되지 않아 output === ""
array.foo = "foo" // 숫자 외 프로퍼티 설정 가능
output = "";
for (const key in array) { output += key + " "; }
// output === "foo "
Object.prototype.myMethod = function () {}; // 새 인스턴스 메서드 추가
output = "";
for (const key in array) { output += key + " "; }
// output === "foo myMethod " (배열도 객체이므로)
// array.length === 3
```
ECMA-262 제5판(JavaScript 1.6, ActionScript 3.0)부터는 배열의 `forEach` 메서드를 사용하여 요소를 반복할 수 있다.
```javascript
array.forEach(function (변수) {
문
});
```
ECMA-262 제6판(ECMAScript 2015)부터는 `for...of` 문으로 배열 등 iterable 객체의 값으로 반복 처리가 가능하다.
```javascript
for (변수 of 객체) {
문
}
3.6. 펄
Perl에서 `foreach` (더 짧은 `for`와 동일)는 리스트의 요소를 순회하는 데 사용될 수 있다. 반복할 컬렉션을 나타내는 표현식은 리스트 컨텍스트에서 평가되며, 결과 리스트의 각 항목은 차례로 루프 변수에 별칭으로 지정된다.
리스트 리터럴 예시:
```perl
foreach (1, 2, 3, 4) {
print $_;
}
```
배열 예시:
```perl
foreach (@arr) {
print $_;
}
```
```perl
foreach $x (@arr) { #$x is the element in @arr
print $x;
}
```
해시 예시:
```perl
foreach $x (keys %hash) {
print $x . " = " . $hash{$x}; # $x is a key in %hash and $hash{$x} is its value
}
```
컬렉션 멤버의 직접적인 수정:
```perl
@arr = ( 'remove-foo', 'remove-bar' );
foreach $x (@arr){
$x =~ s/remove-//;
}
# Now @arr = ('foo', 'bar');
```
Perl에서의 구문은 다음과 같다.
```perl
foreach 변수 (리스트) {
문
}
```
이 루프는 대략 다음과 같은 순서로 실행된다.
1. 변수에 리스트의 어떤 요소에 대한 참조를 대입한다.
2. 문을 실행한다.
3. 모든 요소를 참조하지 않은 경우에는 변수에 "다음 요소"를 대입하고 문 실행으로 돌아간다.
여기서, 선형 리스트나 배열 등 요소의 순서가 정해져 있는 것은, 일반적으로 그 순서대로 루프가 실행되므로, 이 경우 다음과 거의 같다.
```perl
for ( my $i = 0; $i < @list; $i++ ) {
변수 = $list[$i];
문
}
```
단, 해시 테이블로 구현된 연관 배열 등, 요소의 순서 관계가 정해져 있지 않은 "컬렉션"의 경우, 그 참조되는 순서는 정해져 있지 않다.
`foreach` 키워드를 사용한다. Perl에서 `for`와 `foreach`는 서로 바꿔 사용할 수 있다.
```perl
foreach 변수 (컬렉션) {
문
}
3.7. PHP
PHP에서는 `foreach` 루프를 사용하여 배열을 순회한다.
기본적인 사용 방법은 다음과 같다.
```php
foreach ($set as $value) {
// $value에 대해 무언가를 수행;
}
```
배열의 키와 값을 모두 얻으려면 다음과 같이 작성한다.
```php
foreach ($set as $key => $value) {
echo "{$key}는 {$value}의 값을 가짐.";
}
```
컬렉션의 각 요소를 직접 수정할 수도 있다.
```php
$arr = array(1, 2, 3);
foreach ($arr as &$value) { // & 기호 사용, $value는 $arr 내부 값에 대한 참조
$value++;
}
// $arr = array(2, 3, 4);
// 키와 값을 모두 사용하는 경우
foreach ($arr as $key => &$value) {
$value++;
}
```
awk에서도 `foreach`를 사용하여 연관 배열을 처리할 수 있다.
```awk
for (변수 in 배열) {
문장
}
```
PHP의 `foreach`문은 다음과 같은 형태를 가진다.
```php
foreach (배열 as 변수) {
문장
}
```
```php
foreach (배열 as 변수1 => 변수2) {
문장
}
```
PHP에서 첫 번째 형태는 다른 언어와 동일하게 동작하지만, 두 번째 형태는 변수1에 배열 첨자를, 변수2에 해당 요소의 값을 할당한다.
3.8. 파이썬
파이썬에서 `for` 문은 다음과 같이 사용한다.
```python
for item in iterable_collection:
# item으로 무엇인가를 한다.
```
파이썬의 튜플 할당은 `for` 루프에서 유용하게 사용되며, 사전의 (키, 값) 쌍을 반복하는 것을 간편하게 해준다.
```python
for key, value in some_dict.items(): # 사전 직접 반복은 키를 반복한다.
# key와 value로 작업을 한다.
```
파이썬에서 `for ... in`은 유일한 `for` 루프 형태이다. 다른 언어의 "카운터" 루프와 비슷한 동작을 구현하려면 `range` 함수를 사용한다.
```python
for i in range(len(seq)):
# seq[i]에 대해 무엇인가를 한다.
```
`enumerate` 함수를 사용하면 인덱스와 값을 함께 얻을 수 있어 더 파이썬다운 코드를 작성할 수 있다.
```python
for i, item in enumerate(seq):
# item으로 작업을 한다.
# 필요하다면 seq[i]에 다시 할당할 수 있다.
```
파이썬의 `for` 문은 `else` 절과 함께 사용될 수 있다. `else` 블록은 `for` 루프가 break 등으로 중단되지 않고 정상적으로 완료되었을 때 실행된다.
```python
for 변수 in 반복_가능한_컬렉션:
문장_1
if 조건식:
문장_2
break
문장_3
else:
문장_4
```
3.9. 루비
루비에서는 `collection.each do |item| ... end` 또는 `for item in collection ... end` 구문을 사용하여 foreach 루프를 구현한다.
set.each do |item|
# item에 대해 무엇인가 수행
end
for item in set
# item에 대해 무엇인가 수행
end
해시와 함께 사용할 때는 다음 구문을 사용한다.
set.each do |key,value|
# key에 대해 무엇인가 수행
# value에 대해 무엇인가 수행
end
루비에서 `for` 루프는 아래의 이터레이터 구문과 변수의 스코프를 제외하고 동일하다.
```ruby
for 변수 in 컬렉션
문
end
```
```ruby
컬렉션.each do |변수|
문
end
```
루비에서는 주로 이터레이터 구문(`collection.each do |item| ... end`)이 선호되는 경향이 있다.
3.10. 기타 언어
ActionScript, Ada, D, 델파이, Eiffel, Go, Groovy, Haxe, Lua, MATLAB, Objective-C, OCaml, ParaSail, 파스칼, R, Racket, Raku, Rust, Scala, Scheme, 스몰토크, Swift, SystemVerilog, Tcl, Visual Basic (.NET), Windows PowerShell 등 많은 언어에서 foreach 루프 또는 유사 기능을 지원한다.
각 언어별 예시는 다음과 같다.
* ActionScript
ActionScript는 각 인덱스에서 값을 가져오는 `for each .. in`을 지원한다.
```actionscript3
var foo:Object = {
"apple":1,
"orange":2
};
for each (var value:int in foo) {
trace(value);
}
// returns "1" then "2"
```
각 인덱스에서 키를 가져오는 `for .. in`도 지원한다.
```actionscript3
for (var key:String in foo) {
trace(key);
}
// returns "apple" then "orange"
```
* Ada
Ada는 일반적인 for 루프의 일부로 foreach 루프를 지원한다. X가 배열이라고 가정하면 다음과 같다.
```Ada
for I in X'Range loop
X (I) := Get_Next_Element;
end loop;
```
이 구문은 주로 배열에 사용되지만, 전체 반복이 필요할 때 다른 유형에서도 작동한다. Ada 2012는 모든 종류의 컨테이너(배열, 목록, 맵 등)에 대한 foreach 루프로 루프를 일반화했다.
```Ada
for Obj of X loop
-- Obj에 대한 작업
end loop;
```
* D
```D
foreach(item; set) {
// item에 무언가 수행
}
```
또는
```D
foreach(argument) {
// 값 전달
}
```
* 델파이
Foreach 루프 지원은 델파이 2005에 추가되었으며, `var` 섹션에 선언해야 하는 열거자 변수를 사용한다.
```Delphi
for 열거자 in 컬렉션 do
begin
// 여기에 뭔가 한다
end;
```
* Eiffel
Eiffel 루프 구문의 반복(foreach) 형태는 키워드 `across`로 시작한다. 다음 예는 `my_list` 구조체의 모든 요소를 출력한다.
```Eiffel
across my_list as ic loop print (ic.item) end
```
지역 엔티티 `ic`는 라이브러리 클래스 `ITERATION_CURSOR`의 인스턴스이다. 커서의 기능 `item`은 각 구조체 요소에 대한 접근을 제공한다. 특수한 반복 알고리즘을 처리하기 위해 클래스 `ITERATION_CURSOR`의 자손을 만들 수 있다. 반복할 수 있는 객체의 유형(예시에서 `my_list`)은 라이브러리 클래스 `ITERABLE`을 상속하는 클래스를 기반으로 한다. Eiffel 루프의 반복 형태는 키워드 `loop`를 `all` (전칭 양화) 또는 `some`(존재 양화)로 대체할 때 부울 식으로도 사용할 수 있다. 다음은 `my_list`의 모든 항목이 세 개보다 큰 개수를 가지면 참이 되는 부울 식이다.
```Eiffel
across my_list as ic all ic.item.count > 3 end
```
다음은 적어도 하나의 항목이 세 개보다 큰 개수를 가지면 참이 된다.
```Eiffel
across my_list as ic some ic.item.count > 3 end
```
* Go
Go의 foreach 루프는 배열, 슬라이스, 문자열, 맵 또는 채널을 반복하는 데 사용될 수 있다. 두 개의 값을 사용하는 형식은 인덱스/키(첫 번째 요소)와 값(두 번째 요소)을 가져온다.
```go
for index, value := range someCollection {
// index와 value에 무언가를 한다
}
```
하나의 값을 사용하는 형식은 인덱스/키(첫 번째 요소)를 가져온다.
```go
for index := range someCollection {
// index에 무언가를 한다
}
```
* Groovy
Groovy는 배열, 리스트, 범위와 같은 컬렉션에 대한 `for` 루프를 지원한다.
```groovy
def x = [1,2,3,4]
for (v in x) // 4개 요소 배열 x를 순회합니다.
{
println v
}
for (v in [1,2,3,4]) // 4개 요소 리터럴 리스트를 순회합니다.
{
println v
}
for (v in 1..4) // 1..4 범위를 순회합니다.
{
println v
}
```
Groovy는 또한 배열 인덱스를 사용하는 C 스타일 for 루프를 지원한다.
```groovy
for (i = 0; i < x.size(); i++)
{
println x[i]
}
```
Groovy의 컬렉션은 `each` 키워드와 클로저를 사용하여 반복할 수도 있다. 기본적으로 루프 더미는 `it`으로 지정된다.
```groovy
x.each{ println it } // x 배열의 모든 요소를 출력합니다.
x.each{i-> println i} // 위의 줄과 동일하며, 루프 더미가 "i"로 명시적으로 지정됩니다.
```
* Haskell
Haskell은 `mapM_`와 `forM_` ( `mapM_`의 인자를 바꾼 것)를 사용하여 모나드 액션을 통해 리스트를 순환할 수 있다. `mapM_`와 `forM_`는 [http://hackage.haskell.org/package/base-4.6.0.1/docs/Control-Monad.html Control.Monad]에서 제공된다.
| 코드 | 출력 |
|---|---|
* Haxe
```actionscript
for (value in iterable) {
trace(value);
}
Lambda.iter(iterable, function(value) trace(value));
```
* Lua
숫자 인덱스 값만 반복하는 경우:
```lua
for index, value in ipairs(array) do
-- do something
end
```
모든 인덱스 값 반복하는 경우:
```lua
for index, value in pairs(array) do
-- do something
end
```
* MATLAB
```MATLAB
for item = array
%do something
end
```
* Mint
Mint는 다음과 같은 구문을 사용하여 for each 루프를 지원한다.
```Ruby
for each element of list
/* 'Do something.' */
end
```
* Objective-C
빠른 열거라고도 불리는 ForEach 루프는 Objective-C 2.0부터 지원된다. NSArray, NSDictionary(키를 반복), NSSet 등을 포함하여 NSFastEnumeration 프로토콜을 구현하는 모든 객체를 반복하는 데 사용할 수 있다.
```objc
NSArray *a = [NSArray new]; // 모든 컨테이너 클래스를 대체할 수 있습니다.
for(id obj in a) { // 동적 타이핑이 사용됩니다. 저장된 객체의 타입
// 'a'는 알 수 없습니다. 배열은 다양한 객체를 포함할 수 있습니다.
printf("%s\n", [[obj description] UTF8String]); // %s와 함께 UTF8String을 사용해야 합니다.
NSLog(@"%@", obj); // 객체로 둡니다.
}
```
* OCaml
OCaml은 함수형 프로그래밍 언어이다. 따라서 foreach 루프에 해당하는 것은 리스트와 배열에 대한 라이브러리 함수로 구현할 수 있다.
리스트의 경우:
```ocaml
List.iter (fun x -> print_int x) [1;2;3;4];;
```
또는 다음과 같은 짧은 형태로 작성할 수 있다.
```ocaml
List.iter print_int [1;2;3;4];;
```
배열의 경우:
```ocaml
Array.iter (fun x -> print_int x) [|1;2;3;4|];;
```
또는 다음과 같은 짧은 형태로 작성할 수 있다.
```ocaml
Array.iter print_int [|1;2;3;4|];;
```
* ParaSail
ParaSail 병렬 프로그래밍 언어는 컨테이너에 대한 일반적인 "for each" 반복자를 포함하여 여러 종류의 반복자를 지원한다.
```parasail
var Con : Container
// ...
for each Elem of Con concurrent loop // loop may also be "forward" or "reverse" or unordered (the default)
// ... do something with Elem
end loop
```
* 파스칼
파스칼에서는 ISO 표준 10206:1990에서 집합 자료형에 대한 반복을 도입하여 다음과 같이 사용할 수 있다.
```Pascal
var
elt: ElementType;
eltset: set of ElementType;
{...}
for elt in eltset do
{ ... do something with elt }
```
* R
```R
for (item in object) {
# item으로 무엇인가를 한다.
}
```
`for ... in`은 R에서 유일한 `for` 루프 형태이므로, 다른 언어에서 발견되는 "카운터" 루프에 해당하는 것은 다음과 같다.
```R
for (i in seq_along(object)) {
# objecti로 무엇인가를 한다.
}
```
* Racket
```racket
(for ([item set])
(do-something-with item))
```
또는 기존의 Scheme `for-each` 함수를 사용한다.
```racket
(for-each do-something-with a-list)
```
`do-something-with`는 한 개의 인수를 갖는 함수이다.
* Raku
Raku는 Perl의 자매 언어로서, 목록의 요소를 순회하기 위해 `for`를 사용해야 한다(`foreach`는 허용되지 않음). 순회할 컬렉션을 나타내는 표현식은 리스트 컨텍스트에서 평가되지만 기본적으로 평탄화되지 않으며, 결과 리스트의 각 항목은 차례로 루프 변수에 별칭이 지정된다.
리스트 리터럴 예시:
```perl6
for 1..4 {
.say;
}
```
배열 예시:
```perl6
for @arr {
.say;
}
```
* Rust
`for` 루프는 `for
```Rust
let mut numbers = vec![1, 2, 3];
// 불변 참조:
for number in &numbers { // IntoIterator::into_iter(&numbers) 호출
println!("{}", number);
}
for square in numbers.iter().map(|x| x * x) { // numbers.iter().map(|x| x * x)는 Iterator를 구현한다.
println!("{}", square);
}
// 가변 참조:
for number in &mut numbers { // IntoIterator::into_iter(&mut numbers) 호출
*number *= 2;
}
// "[2, 4, 6]" 출력:
println!("{:?}", numbers);
// Vec를 소비하고 이터레이터를 생성:
for number in numbers { // IntoIterator::into_iter(numbers) 호출
// ...
}
// "이동된 값의 차용" 오류 발생:
// println!("{:?}", numbers);
```
* Scala
```Scala
// 수정된 요소의 목록 반환
items map { x => doSomething(x) }
items map multiplyByTwo
for {x <- items} yield doSomething(x)
for {x <- items} yield multiplyByTwo(x)
// 아무것도 반환하지 않고, 작업만 수행
items foreach { x => doSomething(x) }
items foreach println
for {x <- items} doSomething(x)
for {x <- items} println(x)
// for-구문에서의 패턴 매칭 예시
for ((key, value) <- someMap) println(s"$key -> $value")
```
* Scheme
```Scheme
(for-each do-something-with a-list)
```
`do-something-with`는 한 개의 인수를 받는 함수이다.
* 스몰토크
```Smalltalk
컬렉션 do: [:항목| "항목에 대해 무언가 수행" ]
```
스몰토크는 리스프의 영향을 받아 언어 구문으로 반복 구문이 존재하지 않는다. 따라서 `#do:` 셀렉터와 블록 객체를 사용한 메시지로 표현한다.
* Swift
Swift는 `for`…`in` 구문을 사용하여 컬렉션의 멤버를 반복한다.
```objc
for thing in someCollection {
// do something with thing
}
```
`for`…`in` 루프는 닫힌 범위 및 반 열린 범위 구문과 함께 사용하여 루프 본문을 특정 횟수만큼 반복하는 데 자주 사용된다.
```objc
for i in 0..<10 {
// 0..<10은 반 열린 범위를 구성하므로 루프 본문은
// i = 0, i = 1, …, i = 9에 대해 반복됩니다.
}
for i in 0...10 {
// 0...10은 닫힌 범위를 구성하므로 루프 본문은
// i = 0, i = 1, …, i = 9, i = 10에 대해 반복됩니다.
}
```
* SystemVerilog
SystemVerilog는 `foreach` 키워드를 사용하여 모든 차원의 모든 벡터 또는 배열 유형에 대한 반복을 지원한다.
간단한 예제는 정수 배열을 반복한다.
| 코드 | 출력 |
|---|---|
더 복잡한 예제는 정수 배열의 연관 배열을 반복한다.
| 코드 | 출력 |
|---|---|
* Tcl
Tcl은 리스트를 반복하기 위해 foreach를 사용한다. 둘 이상의 반복자 변수를 지정할 수 있으며, 이 경우 리스트에서 순차적인 값이 할당된다.
| 코드 | 출력 |
|---|---|
둘 이상의 리스트를 동시에 반복할 수도 있다. 다음 예에서 `i`는 첫 번째 리스트의 순차적인 값을, `j`는 두 번째 리스트의 순차적인 값을 가정한다.
| 코드 | 출력 |
|---|---|
* Visual Basic .NET
```vb
For Each item In enumerable
' item으로 무언가 하기.
Next
```
또는 형식 유추 없이
```vb
For Each item As type In enumerable
' item으로 무언가 하기.
Next
```
* Windows PowerShell
```PowerShell
foreach ($item in $set) {
# $item에 대해 뭔가 수행
}
```
파이프라인에서
```PowerShell
$list | ForEach-Object {Write-Host $_}
# 또는 별칭 사용
$list | foreach {write $_}
$list | % {write $_}
4. 쉘 스크립트
csh 계열에서는 `foreach`를 사용하고, sh 계열에서는 `for`를 사용한다. 실용적으로는 리스트 부분에 와일드카드를 포함한 파일 목록을 쓰는 경우가 많다.
csh 계열:
foreach 변수 ( 리스트 )
문
end
sh 계열:
for 변수 in 리스트
do
문
done
5. PL/SQL
오라클의 PL/SQL에도 ForEach와 유사한 기능인 커서가 구현되어 있다. 커서는 용도가 한정적이므로 번외편으로 소개한다.
SELECT 문으로 가져온 여러 레코드를 커서를 사용하여 순차적으로 출력하는 PL/SQL 문은 다음과 같다.
```sql
DECLARE
CURSOR C IS
SELECT
*
FROM
TBL1
WHERE
TBL1.FIELD1 >= 100;
BEGIN
FOR D IN C LOOP
DBMS_OUTPUT.PUT_LINE(D.FIELD1 || ' ' || D.FIELD2 || ' ' || D.FIELD3);
END LOOP;
END;