Foreach文

foreach文またはfor-each文とは、プログラミング言語においてリストや連想配列などの「コレクション」と呼ばれるデータ構造の各要素に対して与えられた文の実行を繰り返すループ文である。foreach文はしばしばfor文の一部という位置付けにあるが、for文と異なり要素の参照順序が定義されないことがある。

1. 処理の流れ
--------

Perlでの構文は以下のようになる。

foreach 変数  { 文 }<WtXmlEndTag />

このループはだいたい次のような手順で実行される。

変数にリストの中のある要素への参照を代入する。
文を実行する。
全要素を参照し終わっていない場合は、変数に「次の要素」を代入して文の実行へ戻る。ここで、線形リストや配列など要素の順序が決まっているものは、通常その順序でループが実行されるので、この場合以下とほぼ同様である。

for  { 変数 = $list[$i]; 文 }<WtXmlEndTag />

ただし、ハッシュテーブルによって実装された連想配列など、要素の順序関係が決められていない「コレクション」の場合、その参照される順序は不定である。

2. 文法
-----

2.1. awk
--------

awkにおいても連想配列の処理を可能にしている。

for  { 文 }<WtXmlEndTag />

2.2. C#
-------

foreach  { 文 }<WtXmlEndTag /> コレクションは配列のほか、IEnumerableもしくはIEnumerableを実装したオブジェクトでもよい。実際の要件は特定のインターフェイスを実装していることではなく、GetEnumeratorという名前のメソッドを実装してさえいれば何でもよい。

2.3. C++
--------

C++11にて、範囲ベースの for ループが言語仕様として追加されている。

for  { 文 }<WtXmlEndTag /> 上記で「コレクション」と記した箇所には、配列のほか、std::vectorやstd::arrayのような標準ライブラリにおいてコンテナに分類される各種のオブジェクトなども使用できる。

そのほか、1998年の標準規格化当初からC++標準ライブラリにfor_eachアルゴリズムが存在する。

関数オブジェクト = std::for_each;<WtXmlEndTag /> C++11では、C#同様に型推論およびラムダ式を組み合わせることで、上記の構文が威力を発揮するようになる。

なお、C++/CLI言語およびMicrosoft Visual C++ 2005以降の独自拡張機能では、for each文を使用できるが、不安定で正常に動作しない場合があるdate=2017年9月}}。また、これはC++11における範囲ベース for ループとは互換性がない。

for each  { 文 }<WtXmlEndTag />

2.4. D
------

式を評価し、その結果は静的配列、動的配列、連想配列、構造体、クラスでなければいけない。式部分が配列である場合は、変数は複数宣言することができる。

foreach  { 文 }<WtXmlEndTag />

2.5. Go
-------

Goのforeachループは、配列、スライス、文字列、マップ、チャンネルのループに使用できる。

2値形式を使用すると、インデックス/キーと値を得ることができる。

for index, value := range コレクション { // インデックスと値に何かをする }<WtXmlEndTag />

単値のフォームを使って、index/keyを取得する。

for index := range コレクション { // インデックスに何かをする }<WtXmlEndTag />

2.6. Java
---------

Java 5で導入された拡張for文  がforeach文に相当する。コレクションにはname=java.util.Collectionなど、name=java.lang.Iterableを実装する式を配置することができる。

for  { 文 }<WtXmlEndTag /> また、文ではなくメソッドであるが

コレクション.forEach<WtXmlEndTag /> の様に .forEach メソッドにラムダ関数を渡しコレクションの要素に対し反復処理を行うことができる。

2.7. JavaScript, ActionScript
-----------------------------

オブジェクトの反復処理にはfor-in文を用いる。変数にはプロパティ名が代入されるので、プロパティの値は式 オブジェクト[変数] で取得する。

for  { 文 }<WtXmlEndTag />

JavaScriptのfor-in文は、ユーザー定義のプロパティについて、プロトタイプチェーンをさかのぼって反復処理を行う。このため、特に配列に対してfor-in文を用いると、他の言語とは異なる挙動をすることがある。

const array = new Array; let output = ""; for  { output += key + " "; } // このとき array.length === 3 であるが、 // array にユーザー側から配列要素を定義していないので、 // output === "" である。

// 配列もオブジェクトなので、数値以外のプロパティを設定できる。 array.foo = "foo"

output = ""; for  { output += key + " "; } // このとき output === "foo " である。

// オブジェクトに新しいインスタンスメソッドを追加してみる。 Object.prototype.myMethod = function  {};

output = ""; for  { output += key + " "; } // 配列もオブジェクトなので、このとき output === "foo myMethod " である。

// なおもちろん、この時点でも array.length === 3 である。<WtXmlEndTag />

ECMA-262第5版  からは、ArrayインスタンスにforEachメソッドが追加された。このメソッドは本項で説明されているforeach文と同様に配列の要素を反復して文を実行する。

array.forEach { 文 });<WtXmlEndTag />

ECMA-262第6版  からは、配列などのiterableオブジェクトの値で反復処理をするfor-of文も導入された。

for  { 文 }<WtXmlEndTag />

2.8. Perl
---------

foreachキーワードを使用する。Perlにおいて、forとforeachは互いに交換可能である。

foreach 変数  { 文 }<WtXmlEndTag />

2.9. PHP
--------

foreach  { 文 }<WtXmlEndTag />

foreach  { 文 }<WtXmlEndTag />

前者の場合、処理手順は他の言語と同様だが、後者の場合、変数1に配列の添字が、変数2に要素が代入される。

2.10. Python
------------

Pythonにおけるfor文は、Cのようにカウンタ変数の増減や評価を直接記述することはできず、他の言語におけるforeach文と同等である。

基本的なイテレータブルコレクションへの反復処理::for 変数 in イテレータブルコレクション : 文<WtXmlEndTag />

Pythonのタプル代入は、forループでも利用でき、辞書オブジェクトのペアを反復処理することも容易にできる。

辞書オブジェクトへの反復処理::for key, value in 辞書オブジェクト.items: 文<WtXmlEndTag />

for ... inがPythonの唯一のforループなので、他の言語で見られるカウンターループ相当には、組み込み関数 range}}を用いる。

カウンターループ::for i in range):

seq[i] への処理<WtXmlEndTag />

組み込み関数 enumerate}}関数を用いると、添字と要素の対でシーケンスへの繰り返しができる。この場合もタプル代入を利用する。

添字と要素の対で反復処理::for i, item in enumerate: 文<WtXmlEndTag />

Pythonのfor文はelseを伴うことができす。

breakとelse::for 変数 in イテレータブルコレクション : 文１ if 条件式: 文２ break 文３ else 文４<WtXmlEndTag />

条件式が真であった場合、文２が実行された後のbreak文で、for文のループを中断する。 elseのブロック文４は、for文のループを完走した場合のみ実行され、breakで中断した場合は実行されない。

2.11. Ruby
----------

for 変数 in コレクション 文 end<WtXmlEndTag /> これは以下のイテレータ構文と、変数のスコープを除いて等価である。

コレクション.each do |変数| 文 end<WtXmlEndTag /> なお、Rubyに関してはもっぱら後者の構文が好まれる傾向にある。

2.12. Rust
----------

forループは という構造を持つ。 これは暗黙のうちに式の [1] メソッドを呼び出し、結果として得られる値を使用する。 これは [2] trait を実装しなければならない。 式がそれ自体イテレータである場合、それは [3] を通して for ループによって直接使用され、イテレータは変更されずに返される。 ループは、ループ本体を実行する前に、イテレータの Iterator::next メソッドを呼び出す。Iterator::next が Some を返した場合、内部の値が pattern に割り当てられ、ループ本体が実行される。None を返した場合、ループは終了する。

let mut numbers = vec![1, 2, 3];

// Immutable reference: for number in &numbers { // calls IntoIterator::into_iter println!; }

for square in numbers.iter.map { // numbers.iter.map implements Iterator println!; }

// Mutable reference: for number in &mut numbers { // calls IntoIterator::into_iter

number *= 2;}

// prints "[2, 4, 6]": println!;

// Consumes the Vec and creates an Iterator: for number in numbers { // calls IntoIterator::into_iter // ... }

// Errors with "borrow of moved value": // println!;<WtXmlEndTag />

2.13. Smalltalk
---------------

コレクション do: [ :変数 | 文 ].<WtXmlEndTag /> SmalltakはLispの影響を受けており、言語構文として反復構文が存在しない。そのため、#do:セレクターとブロックオブジェクトを使ったメッセージで表現する。上記ではメッセージを受け取るレシーバーをコレクションと表記しているが、#do:は#do:を実装しCollectionあるいはIterableを継承していれば良く、入力ストリームや高々1回しか実行しないオブジェクト、無限数列などもレシーバーとして指定できる。また、イテレーターのような反復状態を持つ専用のクラスが必要なく#do:のメソッドだけで完結するため、C++のような方式に比べ実装が単純になっている。またフィルターも容易であり、フィルター用のクラスも多数存在する。#do:は列挙プロトコルに属しており、#do:を実装しCollectionあるいはIterableを継承したオブジェクトは、#select:, #collect:, #detect:, #inject:into:といったその他の列挙プロトコルが同時に使えるようになる。

戻り値を返さない。
#do:の引数としてValueAdapter  を指定する。
引数として指定したValueAdapterが0回以上の反復に対応している。 do: [ :each | 文 ].<WtXmlEndTag /> 例えば一定回数反復したい場合も#do:を使い、上記のようになる。

Smalltalkは後発の無名関数を備えたオブジェクト指向言語に広く影響を与えており、Ruby、ECMAScript、Java、C#も同様のライブラリを備えつつある。

2.14. Visual Basic
------------------

For Each 変数 In コレクション 文 Next 変数<WtXmlEndTag />

2.15. PowerShell
----------------

foreach  { 文 }<WtXmlEndTag />

2.16. HSP
---------

foreach 変数 文 loop

2.17. なでしこ
----------

を反復。 　　文

変数は「それ」に代入される。

2.18. シェルスクリプト
--------------

cshではforeachと書き、shではforと書く。実用上リストの部分にはワイルドカードを含むファイル列を書くことが多い。

csh系

foreach 変数  文 end<WtXmlEndTag /> sh系

for 変数 in リスト do 文 done<WtXmlEndTag />

3. 番外編
------

3.1. PL/SQL
-----------

OracleのPL/SQLにも、カーソルというForEachと似たような機能が実装されている。 カーソルは用途が限定されているため、番外編として紹介する。

SELECT文でとってきた複数レコードを、カーソルを使って順繰り出力するPL/SQL文を示す。

DECLARE CURSOR C IS SELECT

FROM TBL1 WHERE TBL1.FIELD1 >= 100; BEGIN FOR D IN C LOOP DBMS_OUTPUT.PUT_LINE; END LOOP; END;<WtXmlEndTag />

4. 参照
-----

5. 関連項目
-------

for文
while文
goto文
イテレータ

ru:Цикл просмотра