4D v18For each...End for each |
||||||||||||||||||||||
|
4D v18
For each...End for each
|
コレクション内をループ | エンティティセレクション内をループ | オブジェクト内をループ | |
Current_Item 引数の型 | コレクション要素と同じ型の変数 | エンティティ | テキスト変数 |
Expression 引数の型 | コレクション(同じ型の要素) | エンティティセレクション | オブジェクト |
ループ数(デフォルト) | コレクションの要素数 | セレクション内のエンティティ数 | オブジェクトのプロパティ数 |
begin / end 引数のサポート | サポートする | サポートする | サポートしない |
For each...End for each がCollection 型のExpression 引数に対して使用された場合、Current_Item 引数はコレクション要素と同じ型の変数です。デフォルトでは、ループの回数はコレクションの項目数に基づいています。
コレクションは同じ型の要素しか含んではいけません。そうでない場合には、Current_Item 変数に他の型の値が代入されたときにエラーが生成されます。
各ループの繰り返しにおいて、Current_Item 変数には、合致するコレクションの要素が自動的に代入されます。このとき、以下の点に注意する必要があります:
数値のコレクションに対して、統計情報を計算したい場合を考えます:
C_COLLECTION($nums)
$nums:=New collection(10;5001;6665;33;1;42;7850)
C_LONGINT($item;$vEven;$vOdd;$vUnder;$vOver)
For each($item;$nums)
If($item%2=0)
$vEven:=$vEven+1
Else
$vOdd:=$vOdd+1
End if
Case of
:($item<5000)
$vUnder:=$vUnder+1
:($item>6000)
$vOver:=$vOver+1
End case
End for each
//$vEven=3, $vOdd=4
//$vUnder=4,$vOver=2
For each...End for each がEntity selection 型のExpression 引数に対して使用された場合、Current_Item 引数は現在処理されているエンティティです。
ループの回数はエンティティセレクション内のエンティティの数に基づいています。各ループの繰り返しにおいて、Current_Item 引数には、現在処理されているエンティティセレクション内のエンティティが自動的に代入されます。
注: エンティティセレクションに、途中で他のプロセスによって削除されたエンティティが含まれていた場合、そのエンティティはループにおいて自動的にスキップされます。
カレントエンティティに対して行われた適用された変更は、entity.save( ) を使用して明示的に保存する必要があることに注意してください。
エンティティセレクション内の英国の従業員の給与を引き上げたい場合を考えます:
C_OBJECT(emp)
For each(emp;ds.Employees.query("country='UK'"))
emp.salary:=emp.salary*1,03
emp.save()
End for each
For each...End for each がObject 型のExpression 引数に対して使用された場合、Current_Item 引数は現在処理されているプロパティ名が自動的に代入されているテキスト変数です。
オブジェクトのプロパティは作成順に処理されていきます。ループ中、プロパティをオブジェクトに追加/削除することが可能ですが、その場合でも残りのループ回数は、オブジェクトの元のプロパティ数に基づいているため、変化しません。
以下のオブジェクトにおいて、名前を全て大文字に変えたい場合を考えます:
{ "firstname": "gregory", "lastname": "badikora", "age": 20 }
以下のように書くことができます:
For each(property;vObject)
If(Value type(vObject[property])=Is text)
vObject[property]:=Uppercase(vObject[property])
End if
End for each
{ "firstname": "GREGORY", "lastname": "BADIKORA", "age": 20 }
任意のbegin と end 引数を使用することで、繰り返しに制限を定義することができます。
注: begin と end 引数は、コレクションおよびエンティティセレクション型に対する繰り返しにおいてのみ使用することができます(オブジェクトプロパティのときには無視されます)。
end 引数が省略されている、あるいはend 引数がExpression 引数の要素数より大きい場合、begin 引数の位置から最後の要素まで(含まれる)が繰り返されます。
begin と end 引数が正の値の場合、それらはExpression 引数内の要素の実際の位置を表します。
begin 引数が負の値の場合、それはbegin:=begin+Expression のサイズ として再計算されます(Expression 引数の終端からのオフセットであるとみなされます)。再計算された値も負の値だった場合、begin 引数は0に設定されます。
注: begin 引数が負の値だったとしても、繰り返しそのものは標準の順番で実行されます。
引数が負の値だった場合、それはとしてend:=end+Expression のサイズ として再計算されます。
例:
C_COLLECTION($col;$col2)
$col:=New collection("a";"b";"c";"d";"e")
$col2:=New collection(1;2;3)
C_TEXT($item)
For each($item;$col;0;3)
$col2.push($item)
End for each
//$col2=[1,2,3,"a","b","c"]
For each($item;$col;-2;-1)
$col2.push($item)
End for each
//$col2=[1,2,3,"a","b","c","d"]
For each...End for each の実行は、Until あるいは While 条件をループに追加することでコントロールすることができます。Until(condition) あるいは While(condition) 宣言がループに組み込まれた場合、繰り返しはcondition 引数がtrue に評価されると停止します。
必要に応じて、以下の二つのキーワードのいづれかを渡すことができます:
$colNum:=New collection(1;2;3;4;5;6;7;8;9;10)
$total:=0
For each($num;$colNum)While($total<30) //最初にテストされる
$total:=$total+$num
End for each
ALERT(String($total)) //$total = 36 (1+2+3+4+5+6+7+8)
$total:=1000
For each($num;$colNum)Until($total>30) //最後にテストされる
$total:=$total+$num
End for each
ALERT(String($total)) //$total = 1001 (1000+1)
For each...End for each ループは、共有コレクションおよび共有オブジェクトに対しても使用することができます。
コードがコレクションあるいはオブジェクトプロパティの一つ以上の要素を変更する必要がある場合、Use...End use キーワードを使用する必要があります。必要に応じて、Use...End use キーワードを以下の二つの場所で使用することができます:
プロダクト: 4D
テーマ: プログラミング言語の構成要素
初出: 4D v17
ランゲージリファレンス ( 4D v18)