配列(リスト)の要素を1つずつ処理するには (for / foreach)

各プログラミング言語での、配列(リスト)の要素を1つずつ順番に処理する方法。

for文などの繰り返しの構文が使える言語が多い。

配列やリストの要素に対してではなく、 0から順番にカウンタを回して繰り返し処理をさせる方法は forを参照。

Java

配列をforでループする例

for(int i = 0; i < strArr.length; i++){
  String str = arr[i];
  ...;
}

java.lang.Iterator を使った例

for(Iterator<String> it = strList.iterator(); it.hasNext();){
  String str = it.next();
  ...;
}

Java5からは、以下の拡張for文の利用が可能。(foreach構文)

for(String str: strArr){
  ...;
}

拡張for文の場合 strArr は配列であるか、java.lang.Iterable を実装しているオブジェクトであることが必要。

Scala

ListMapなどたいていのコレクション型にあるforeachメソッドを使えばよい。

Signature:

// scala.collection.Seq[A]
def foreach(f: A => Unit): Unit

foreachの引数には関数を渡すが、Scalaでは関数をいろいろな書き方ができるので、慣れないとわかりづらいかもしれない。以下はいろいろな書き方の例。

val lst = "a" :: "b" :: "c" :: Nil;
lst.foreach { (s: String) => println(s); }

// {} でなくて () でもよい
lst.foreach((s: String) => println(s));

// 関数の引数の型は推論ができれば省略できる
lst.foreach((s) => println(s));

// 関数の引数が1つであれば括弧を省略できる
lst.foreach(s => println(s));

// 関数の引数を1回しか使わない単純な関数であれば _ と書ける
lst.foreach(println(_));

// メソッド名だけ
lst.foreach(println);

一番下は、Perlみたいに省略されまくっているが、Perlの $_ のような暗黙の変数があるのではなく、高階関数の引数のように関数を書くべき場所に単にメソッド名だけを書ける機能である。

foreachメソッドの代わりにfor式を使ってもよい。

for (elem <- list) {
  ...;
}

for式はコンパイラ内部ではforeachメソッドの呼び出しに変換されている。

Scala for式の実体
http://www.ne.jp/asahi/hishidama/home/tech/scala/collection/for.html

PHP

配列をループする例

foreach ($arr as $elem) {
  ...
}

インデックスと値の両方を変数に入れることもできる。

foreach ($arr as $index => $elem) {
  ...
}

この書き方は普通の配列でなくて連想配列の場合に特に便利。

中括弧({})の代わりに以下のようなコロンを使った記法も可能。

foreach ($arr as $elem):
  ...
endforeach;

または別の書き方としてC言語風に

for ($i = 0; $i < $arr.length; $i++) {
  ...
}

ループの中で要素の変数名に値を代入しても配列には影響しないが、 &$elem というふうに書くと、配列に変更を反映させることができる。

$arr = array(10, 20, 30);
foreach ($arr as $elem) {
    $elem = $elem * 10; # この書き方では配列自体には影響しない
}
var_export($arr);
# => array (
#      0 => 10,
#      1 => 20,
#      2 => 30,
#    )

foreach ($arr as &$elem) { # &$elem と書いて参照渡しにする
    $elem = $elem * 10; # 配列に影響する
}
var_export($arr);
# => array (
#      0 => 100,
#      1 => 200,
#      2 => 300,
#    )

Pythonのアンパック代入のように as の右に list() 形式を置くことはPHPではできない。と思ったが、PHP5.5からはできるようになるらしい。

foreach文 | PHP Manual
http://php.net/manual/ja/control-structures.foreach.php

Smarty

{foreach $arr as $value}
  ...
{foreachelse}
  <!-- $arr に要素がひとつもなかった場合 -->
  ...
{/foreach}

ループの最初と最後にだけ特別な処理を入れたい場合、foreachの中で name=hoge のように書くと $smarty.foreach.hoge を使って、処理を振り分けられる。

{foreach $arr as $value name=item}
  {if $smarty.foreach.item.first}
    <!-- 最初の要素の場合 -->
    ...
  {/if}
  ...
  {if $smarty.foreach.item.last}
    <!-- 最後の要素の場合 -->
    ...
  {/if}
{/foreach}

Python

for文の例

for elem in lst:
    ...
    ...

lst にはリスト、タプル、文字列といったシーケンスを使うことができる。文字列に使うと、その中の1文字ずつでループ処理する。シーケンス以外にもイテレータ型を使うこともできる。

lst の要素がさらにリストやタプルなどになっていれば、elem には複数の変数を書くことができ、要素ごとにアンパック代入されてループが実行される。

lst = [[3, "abc"], [4, "def"]]
for a, b in lst:
    print(a, b)
# 出力結果
# 3 abc
# 4 def

変数のスコープは関数なので、elemに最後に代入された要素は for文から脱出後もそのまま保持される。

whileと同じく、 else節を付けることができる。else節は条件を満たさなくなってループを脱出する際に実行される。要素が1つもない場合ではない。ループからbreakで脱出した場合は実行されない。

for elem in lst:
    ...
    ...
else:
    ...
    ...

for文 | Python 2.7 documentation
http://docs.python.jp/2/reference/compound_stmts.html#for

for文 | Python 3 documentation
http://docs.python.jp/3/reference/compound_stmts.html#the-for-statement

Ruby / JRuby

for elem in arr do
  ...
end

do は省略してもよい。

elem の部分には複数の値が入る場合に複数の変数が使える。例:

for i, str in [[1, 'abc'], [2, 'def'], [3, 'ghi']]
  ...
end

配列の Array#each メソッドも使える。 breakでのループの中断は、上記のfor文以外にこのeachメソッドでも使える。

[1, 2, 3].each do |i|
  p i
  break if i == 2
end
# => 1 2

Array#each | Ruby 2.1 リファレンスマニュアル
http://docs.ruby-lang.org/ja/2.1.0/method/Array/i/each.html

Perl

my @arr = ('abc', 'def', 'ghi');
foreach my $elem (@arr) {
  ...;
}

変数名を省略した以下の書き方も可能。この場合、ループの中では要素を $_ で参照する。

my @arr = ('abc', 'def', 'ghi');
foreach (@arr) {
  ...;
}

以下のように修飾子の書き方も可能。この書き方でもループの中では要素を $_ で参照する。

... foreach (@arr);

配列のレファレンスに対して繰り返し処理をしたい場合は、@arr の代わりに @$arr のように書けばよい。

Perlでは forforeach はまったく同じなので、上記のどの例でも foreachfor にしても同じになる。

sh (シェルスクリプト)

例1

for v in foo bar hoge
do
  echo $v
done

例2 (スペース区切りの文字列に対して繰り返し処理)

list="foo bar hoge"
for v in $list
do
  echo $v
done

出力結果(どちらも同じ)

foo
bar
hoge

JavaScript

配列をループする例

for (index in arr) {
  var elem = arr[index];
  ....;
}

CoffeeScriptと違って in の左にくるのは要素のインデックス。

CoffeeScript

配列をループする例

for elem in arr
  ....

JavaScriptと違って in の左にくるのは要素の値。

このサイトは筆者(hydrocul)の個人メモの集合です。すべてのページは永遠に未完成です。