コンテンツにスキップ

英文维基 | 中文维基 | 日文维基 | 草榴社区

「Foreach文」の版間の差分

出典: フリー百科事典『ウィキペディア(Wikipedia)』
削除された内容 追加された内容
Ruby: スコープの違いはある
Cewbot (会話 | 投稿記録)
m Bot作業依頼: sourceタグをsyntaxhighlightタグに置換 (Category:非推奨のsourceタグを使用しているページ) - log
4行目: 4行目:
基本的な構文 ([[Perl]]) は以下のようになる。
基本的な構文 ([[Perl]]) は以下のようになる。


<source lang="perl">
<syntaxhighlight lang="perl">
foreach 変数 (リスト) {
foreach 変数 (リスト) {
}
}
</syntaxhighlight>
</source>


このループはだいたい次のような手順で実行される。
このループはだいたい次のような手順で実行される。
16行目: 16行目:
ここで、[[線形リスト]]や[[配列]]など要素の順序が決まっているものは、通常その順序でループが実行されるので、この場合以下とほぼ同様である。
ここで、[[線形リスト]]や[[配列]]など要素の順序が決まっているものは、通常その順序でループが実行されるので、この場合以下とほぼ同様である。


<source lang="perl">
<syntaxhighlight lang="perl">
for ( my $i = 0; $i < @list; $i++ ) {
for ( my $i = 0; $i < @list; $i++ ) {
変数 = $list[$i];
変数 = $list[$i];
}
}
</syntaxhighlight>
</source>


ただし、[[ハッシュテーブル]]([[連想配列]])については要素の順序関係が決定できないこともあるため、一般に参照順序は不定である。
ただし、[[ハッシュテーブル]]([[連想配列]])については要素の順序関係が決定できないこともあるため、一般に参照順序は不定である。
28行目: 28行目:
=== [[awk]] ===
=== [[awk]] ===
awkにおいても[[連想配列]]の処理を可能にしている。
awkにおいても[[連想配列]]の処理を可能にしている。
<source lang="awk">
<syntaxhighlight lang="awk">
for (変数 in 配列)
for (変数 in 配列)
{
{
}
}
</syntaxhighlight>
</source>


=== [[C Sharp|C#]] ===
=== [[C Sharp|C#]] ===
<source lang="csharp">
<syntaxhighlight lang="csharp">
foreach (変数 in コレクション)
foreach (変数 in コレクション)
{
{
}
}
</syntaxhighlight>
</source>
コレクションは配列のほか、IEnumerableもしくはIEnumerable<T>を実装したオブジェクトでもよい。
コレクションは配列のほか、IEnumerableもしくはIEnumerable<T>を実装したオブジェクトでもよい。


=== [[C++]] ===
=== [[C++]] ===
C++は、2011年での規格改定(通称[[C++11]])にて、[[C++11#範囲に基づく for ループ|範囲ベースの for ループ]]が言語仕様として追加されている。
C++は、2011年での規格改定(通称[[C++11]])にて、[[C++11#範囲に基づく for ループ|範囲ベースの for ループ]]が言語仕様として追加されている。
<source lang="cpp">
<syntaxhighlight lang="cpp">
for (変数 : コレクション)
for (変数 : コレクション)
{
{
}
}
</syntaxhighlight>
</source>
上記で「コレクション」と記した箇所には、配列のほか、std::vectorやstd::arrayのような標準ライブラリにおいて'''コンテナ'''に分類される各種のオブジェクトなども使用できる。
上記で「コレクション」と記した箇所には、配列のほか、std::vectorやstd::arrayのような標準ライブラリにおいて'''コンテナ'''に分類される各種のオブジェクトなども使用できる。


そのほか、1998年の標準規格化当初からC++標準ライブラリにfor_eachアルゴリズム(関数テンプレート)が存在する。
そのほか、1998年の標準規格化当初からC++標準ライブラリにfor_eachアルゴリズム(関数テンプレート)が存在する。
<source lang="cpp">
<syntaxhighlight lang="cpp">
関数オブジェクト = std::for_each(
関数オブジェクト = std::for_each(
先頭イテレータ,
先頭イテレータ,
61行目: 61行目:
関数オブジェクト
関数オブジェクト
);
);
</syntaxhighlight>
</source>
C++11では、C#同様に[[C++11#型推論|型推論]]および[[C++11#ラムダ関数とラムダ式|ラムダ式]]を組み合わせることで、上記の構文が威力を発揮するようになる。
C++11では、C#同様に[[C++11#型推論|型推論]]および[[C++11#ラムダ関数とラムダ式|ラムダ式]]を組み合わせることで、上記の構文が威力を発揮するようになる。


なお、[[C++/CLI]]言語および[[Microsoft Visual C++|Microsoft Visual C++ 2005]]以降の独自拡張機能では、<code>for each</code>文を使用できるが、不安定で正常に動作しない場合がある{{要説明|date=2017年9月}}。また、これは[[C++11]]における範囲ベース for ループとは互換性を持たない。
なお、[[C++/CLI]]言語および[[Microsoft Visual C++|Microsoft Visual C++ 2005]]以降の独自拡張機能では、<code>for each</code>文を使用できるが、不安定で正常に動作しない場合がある{{要説明|date=2017年9月}}。また、これは[[C++11]]における範囲ベース for ループとは互換性を持たない。
<source lang="cpp">
<syntaxhighlight lang="cpp">
for each (変数 in コレクション)
for each (変数 in コレクション)
{
{
}
}
</syntaxhighlight>
</source>


=== [[D言語|D]] ===
=== [[D言語|D]] ===
式を評価し、その結果は静的配列、動的配列、連想配列、構造体、クラスでなければいけない。式部分が配列である場合は、変数は複数宣言することができる。
式を評価し、その結果は静的配列、動的配列、連想配列、構造体、クラスでなければいけない。式部分が配列である場合は、変数は複数宣言することができる。
<source lang="d">
<syntaxhighlight lang="d">
foreach (変数 ; 式) {
foreach (変数 ; 式) {
}
}
</syntaxhighlight>
</source>


=== [[Java]] 5.0以降 ===
=== [[Java]] 5.0以降 ===
拡張[[For文]]などと呼び、Java 5.0 で導入された。For文の特殊なものとして捉えられるが、Foreach文に相当する。
拡張[[For文]]などと呼び、Java 5.0 で導入された。For文の特殊なものとして捉えられるが、Foreach文に相当する。
<source lang="java">
<syntaxhighlight lang="java">
for (変数 : コレクション) {
for (変数 : コレクション) {
}
}
</syntaxhighlight>
</source>


=== [[JavaScript]], [[ActionScript]] ===
=== [[JavaScript]], [[ActionScript]] ===
オブジェクトの反復処理にはfor-in文を用いる。変数にはプロパティ名(連想配列で言うキー)が代入されるので、プロパティの値は式 <code>オブジェクト[変数]</code> で取得する。
オブジェクトの反復処理にはfor-in文を用いる。変数にはプロパティ名(連想配列で言うキー)が代入されるので、プロパティの値は式 <code>オブジェクト[変数]</code> で取得する。


<source lang="javascript">
<syntaxhighlight lang="javascript">
for (var 変数 in オブジェクト) {
for (var 変数 in オブジェクト) {
}
}
</syntaxhighlight>
</source>


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


<source lang="javascript">
<syntaxhighlight lang="javascript">
var array = new Array(3);
var array = new Array(3);
var output = "";
var output = "";
122行目: 122行目:


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


ECMA-262第5版 (JavaScript 1.6, ActionScript 3.0) からは、ArrayインスタンスにforEachメソッドが追加された。
ECMA-262第5版 (JavaScript 1.6, ActionScript 3.0) からは、ArrayインスタンスにforEachメソッドが追加された。


<source lang="javascript">
<syntaxhighlight lang="javascript">
array.forEach(function (変数) {
array.forEach(function (変数) {
});
});
</syntaxhighlight>
</source>


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


<source lang="javascript">
<syntaxhighlight lang="javascript">
for (変数 of オブジェクト) {
for (変数 of オブジェクト) {
}
}
</syntaxhighlight>
</source>


=== [[Perl]] ===
=== [[Perl]] ===
しばしばforが代用とされる。Perlにおいて、forとforeachは同義語である。
しばしばforが代用とされる。Perlにおいて、forとforeachは同義語である。


<source lang="perl">
<syntaxhighlight lang="perl">
foreach 変数 (コレクション) {
foreach 変数 (コレクション) {
}
}
</syntaxhighlight>
</source>


=== [[PHP (プログラミング言語)|PHP]] ===
=== [[PHP (プログラミング言語)|PHP]] ===
<source lang="php">
<syntaxhighlight lang="php">
foreach (配列 as 変数) {
foreach (配列 as 変数) {
}
}
</syntaxhighlight>
</source>


<source lang="php">
<syntaxhighlight lang="php">
foreach (配列 as 変数1 => 変数2) {
foreach (配列 as 変数1 => 変数2) {
}
}
</syntaxhighlight>
</source>


前者の場合、処理手順は他の言語と同様だが、後者の場合、変数1に配列の添字が、変数2に要素が代入される。
前者の場合、処理手順は他の言語と同様だが、後者の場合、変数1に配列の添字が、変数2に要素が代入される。
166行目: 166行目:
=== [[Python]] ===
=== [[Python]] ===
Pythonにおける[[For文]]とは、他の言語におけるForeach文と同等である。
Pythonにおける[[For文]]とは、他の言語におけるForeach文と同等である。
<source lang="python">
<syntaxhighlight lang="python">
for 変数 in コレクション :
for 変数 in コレクション :
</syntaxhighlight>
</source>


=== [[Ruby]] ===
=== [[Ruby]] ===
<source lang="ruby">
<syntaxhighlight lang="ruby">
for 変数 in コレクション
for 変数 in コレクション
end
end
</syntaxhighlight>
</source>
これは以下の[[イテレータ]]構文と、変数のスコープを除いて等価である。
これは以下の[[イテレータ]]構文と、変数のスコープを除いて等価である。
<source lang="ruby">
<syntaxhighlight lang="ruby">
コレクション.each do |変数|
コレクション.each do |変数|
end
end
</syntaxhighlight>
</source>
なお、Rubyに関してはもっぱら後者の構文が好まれる傾向にある。
なお、Rubyに関してはもっぱら後者の構文が好まれる傾向にある。


208行目: 208行目:


=== [[Visual Basic]] ===
=== [[Visual Basic]] ===
<source lang="vb">
<syntaxhighlight lang="vb">
For Each 変数 In コレクション
For Each 変数 In コレクション
Next 変数
Next 変数
</syntaxhighlight>
</source>


=== [[PowerShell]] ===
=== [[PowerShell]] ===
<source lang="powershell">
<syntaxhighlight lang="powershell">
foreach (変数 in コレクション) {
foreach (変数 in コレクション) {
}
}
</syntaxhighlight>
</source>


=== [[Hot Soup Processor|HSP]] ===
=== [[Hot Soup Processor|HSP]] ===
236行目: 236行目:


csh系
csh系
<source lang="csh">
<syntaxhighlight lang="csh">
foreach 変数 ( リスト )
foreach 変数 ( リスト )
end
end
</syntaxhighlight>
</source>
sh系
sh系
<source lang="sh">
<syntaxhighlight lang="sh">
for 変数 in リスト
for 変数 in リスト
do
do
done
done
</syntaxhighlight>
</source>


== 番外編 ==
== 番外編 ==

2020年7月5日 (日) 22:44時点における版

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

処理の流れ

基本的な構文 (Perl) は以下のようになる。

foreach 変数 (リスト) {
    
}

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

  1. 変数にリストの中のある要素への参照を代入する。
  2. 文を実行する。
  3. リストの全要素を参照し終わっていない場合は、変数に未参照の要素を代入して文の実行へ戻る。

ここで、線形リスト配列など要素の順序が決まっているものは、通常その順序でループが実行されるので、この場合以下とほぼ同様である。

for ( my $i = 0; $i < @list; $i++ ) {
    変数 = $list[$i];
    
}

ただし、ハッシュテーブル連想配列)については要素の順序関係が決定できないこともあるため、一般に参照順序は不定である。

文法

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

for (変数 in 配列)
{
  
}
foreach (変数 in コレクション)
{
  
}

コレクションは配列のほか、IEnumerableもしくはIEnumerable<T>を実装したオブジェクトでもよい。

C++は、2011年での規格改定(通称C++11)にて、範囲ベースの for ループが言語仕様として追加されている。

for (変数 : コレクション)
{
  
}

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

そのほか、1998年の標準規格化当初からC++標準ライブラリにfor_eachアルゴリズム(関数テンプレート)が存在する。

関数オブジェクト = std::for_each(
  先頭イテレータ,
  末尾イテレータ,
  関数オブジェクト
);

C++11では、C#同様に型推論およびラムダ式を組み合わせることで、上記の構文が威力を発揮するようになる。

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

for each (変数 in コレクション)
{
  
}

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

foreach (変数 ; ) {
  
}

Java 5.0以降

拡張For文などと呼び、Java 5.0 で導入された。For文の特殊なものとして捉えられるが、Foreach文に相当する。

for (変数 : コレクション) {
  
}

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

for (var 変数 in オブジェクト) {
    
}

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

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

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

output = "";
for (var key in array) { output += key + " "; }
// このとき output === "foo " である。

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

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

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

ECMA-262第5版 (JavaScript 1.6, ActionScript 3.0) からは、ArrayインスタンスにforEachメソッドが追加された。

array.forEach(function (変数) {
    
});

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

for (変数 of オブジェクト) {
    
}

しばしばforが代用とされる。Perlにおいて、forとforeachは同義語である。

foreach 変数 (コレクション) {
  
}
foreach (配列 as 変数) {
  
}
foreach (配列 as 変数1 => 変数2) {
  
}

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

PythonにおけるFor文とは、他の言語におけるForeach文と同等である。

for 変数 in コレクション :
    
for 変数 in コレクション
  
end

これは以下のイテレータ構文と、変数のスコープを除いて等価である。

コレクション.each do |変数|
  
end

なお、Rubyに関してはもっぱら後者の構文が好まれる傾向にある。

コレクション do:
[ :変数 |
 
].

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

  • 戻り値を返さない。(Smalltalkの制約上、正確にはselfを返す)
  • #do:の引数としてValueAdapter (#value:を送ることができるオブジェクト) を指定する。(ブロックはValueAdapterの一種)
  • 引数として指定したValueAdapterが0回以上の反復に対応している。
(1 to: 100) do:
[ :each |
  
].

例えば一定回数反復したい場合も#do:を使い、上記のようになる。

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

For Each 変数 In コレクション
  
Next 変数
foreach (変数 in コレクション) {
  
}
foreach 変数
  文
loop
(リスト)を反復。
  文

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

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

csh系

foreach 変数 ( リスト )end

sh系

for 変数 in リスト
do
  done

番外編

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(D.FIELD1 || ' ' || D.FIELD2 || ' ' || D.FIELD3);
    END LOOP;
END;

関連項目