Tcl – リスト(4) -反復 foreach, lmap-

1つ以上のリストから各要素を1つ以上のループ変数に代入しながらループ本体を繰り返し実行する制御コマンドとしてforeachコマンドとlmapコマンドがあります。

この記事はforeachコマンドとlmapコマンドについて紹介します。

foreachコマンド

[書式]

foreach varname list body
foreach varlist1 list1 ?varlist2 list2 ...? body

foreachコマンドは、1つ以上のリストから各要素を1つ以上のループ変数に代入しながらループ本体を繰り返し実行します。

◇1つのループ変数に1つのリスト

[使用例1]

サンプル:total.tcl 合計を計算する。

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

set var {10 11 12 13 14 15 16}
set sum 0    ;# 初期化 

foreach x $var {
    puts $x
    set sum [expr $sum + $x]
}

puts "合計: $sum"

[実行例]

$ ./total.tcl
10
11
12
13
14
15
16
合計: 91

◇2つのループ変数に1つのリスト

[使用例2]

サンプル:season.tcl 日本語/英語で季節を表示する。

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

set season {春 Spring 夏 Summer 秋 Autumn 冬 Winter}
puts "<四季>"

foreach {jp en} $season {
    puts "$jp $en"
}

[実行例]

$ ./season.tcl
<四季>
春 Spring
夏 Summer
秋 Autumn
冬 Winter

◇1つのループ変数に1つのリストが2つ

[使用例3]

サンプル:season2.tcl

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

foreach jp {春 夏 秋 冬} en {Spring Summer Autumn Winter Cold} {
    lappend x $jp $en
    lappend y [list $jp $en]
}

puts "x = $x"
puts "y = $y"

[実行例]

$ ./season2.tcl
x = 春 Spring 夏 Summer 秋 Autumn 冬 Winter {} Cold
y = {春 Spring} {夏 Summer} {秋 Autumn} {冬 Winter} {{} Cold}

足りない要素は空の値が使用されます。変数yのリストは、listコマンドを使って2つのリストのペアを1つの要素になるようにしています。

lmapコマンド

[書式]

lmap varname list body
lmap varlist1 list1 ?varlist2 list2 ...? body 

lmapコマンドは、1つ以上のリストから各要素を1つ以上のループ変数に代入しながらループ本体を繰り返し実行します。

lmapとforeachの違いは、lmapが結果をリスト値として返すのに対してforeachは値を返しません。

lmapコマンドではループ本体の実行が正常に完了した場合は、本体の結果をアキュムレータリスト(蓄積リスト)に追加します。最終ループが正常に完了すると、アキュムレータリストを返します。

breakおよびcontinueは、forコマンドおよびforeachコマンドの場合と同じように、本体内で呼び出すことができますが、この場合、本体は正常に完了せずに、結果はアキュムレータリストに追加されません。

※lmapコマンドはTcl8.6で追加されました。

参考

accumulator  意味:蓄積器、累算器、蓄電池など

アキュムレータとは、演算処理の結果や中間値を一時的に蓄えておく入れ物です。

lmapコマンドでは、ループ本体を実行する度に実行結果をアキュムレータリストに追加していきます。最終ループが正常に完了すると、アキュムレータリストを返します。

[使用例1]

% set odd {1 3 5 7 9}
1 3 5 7 9

% set even [lmap x $odd {expr $x + 1}]
2 4 6 8 10

# foreachは結果の値を返しません。
% set even [foreach x $odd {expr $x + 1}]
%

上の例は奇数リストから偶数リストを生成しています。

上の例をforeachコマンドを使用してlmapコマンドと同様の処理をさせるには以下のようにします。

% foreach x $odd {lappend y [expr $x + 1]}
% puts $y
2 4 6 8 10

[使用例2]

% set season {春 Spring 夏 Summer 秋 Autumn 冬 Winter}
春 Spring 夏 Summer 秋 Autumn 冬 Winter

% lmap {jp en} $season {list $jp $en}
{春 Spring} {夏 Summer} {秋 Autumn} {冬 Winter}

上の例は日本語、英語の順に並んだ1つのリストから日本語と英語がペアになったリストを生成しています。

[使用例3]

% lmap x {1 2 3} y {A B C} {list $x $y}
{1 A} {2 B} {3 C}

上の例は数字リストと英字リストの2つのリストから数字、英字がペアになったリストを生成しています。

コメント

タイトルとURLをコピーしました