MATLAB に foreach 構造はありますか? その場合、基になるデータが変更された場合 (つまり、オブジェクトがセットに追加された場合) はどうなりますか?
9 に答える
MATLAB のFORループは本質的に静的です。他の言語のfor(initialization;condition;increment)ループ構造とは異なり、反復間でループ変数を変更することはできません。これは、次のコードは、B の値に関係なく、常に 1、2、3、4、5 を出力することを意味します。
A = 1:5;
for i = A
A = B;
disp(i);
end
反復中にデータ構造の変更に対応できるようにしたい場合は、WHILEループの方が適している可能性があります --- 反復ごとにループ条件をテストし、ループ変数の値を設定できます( s) あなたが望むように:
n = 10;
f = n;
while n > 1
n = n-1;
f = f*n;
end
disp(['n! = ' num2str(f)])
ところで、Java (およびおそらく他の言語) のfor-eachループは、反復中にデータ構造が変更されると、未指定の動作を生成します。データ構造を変更する必要がある場合は、反復するコレクション内の要素を追加および削除できる適切なIteratorインスタンスを使用する必要があります。幸いなことに、MATLAB は Java オブジェクトをサポートしているため、次のようなことができます。
A = java.util.ArrayList();
A.add(1);
A.add(2);
A.add(3);
A.add(4);
A.add(5);
itr = A.listIterator();
while itr.hasNext()
k = itr.next();
disp(k);
% modify data structure while iterating
itr.remove();
itr.add(k);
end
ザックは、質問に対する直接的な答えについて正しいです。
興味深いことに、次の 2 つのループは同じようには実行されません。
for i=1:10000
% do something
end
for i=[1:10000]
% do something
end
最初のループは、スカラーである変数i
を作成し、それを C の for ループのように繰り返します。i
ザックが言うように、ループ本体で変更すると、変更された値は無視されることに注意してください。2 番目のケースでは、Matlab は 10k 要素の配列を作成し、配列のすべての要素を調べます。
これが意味することは、
for i=1:inf
% do something
end
動作しますが、
for i=[1:inf]
% do something
end
しません (これは、無限のメモリを割り当てる必要があるためです)。詳細については、 Loren のブログを参照してください。
また、セル配列を反復処理できることにも注意してください。
基本的に、 MATLABの forループは、 foreach機能を含めて非常に柔軟です。ここにいくつかの例があります:
1) 開始、増分、および終了インデックスを定義する
for test = 1:3:9
test
end
2) ベクトルをループする
for test = [1, 3, 4]
test
end
3) 文字列をループする
for test = 'hello'
test
end
4) 1 次元セル配列をループする
for test = {'hello', 42, datestr(now) ,1:3}
test
end
5) 2 次元 cell 配列のループ
for test = {'hello',42,datestr(now) ; 'world',43,datestr(now+1)}
test(1)
test(2)
disp('---')
end
6) 構造体配列のフィールド名を使用する
s.a = 1:3 ; s.b = 10 ;
for test = fieldnames(s)'
s.(cell2mat(test))
end
おお!きちんとした質問。
Matlab の for ループは行列を入力として取り、その列を反復処理します。また、Matlab は事実上すべてを値 (参照渡しなし) で処理するため、for ループの入力のスナップショットを取得するため、不変であることが期待されます。
これを説明するのに役立つ例を次に示します。
>> A = zeros(4); A(:) = 1:16
A =
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
>> i = 1; for col = A; disp(col'); A(:,i) = i; i = i + 1; end;
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
>> A
A =
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
文字列のセル配列を反復処理する場合、ループ変数 ( と呼びましょうf
) は単一要素のセル配列になります。どこにでも書き込む必要f{1}
があるのは面倒です。ループ変数を変更すると、クリーンな回避策が得られます。
% This example transposes each field of a struct.
s.a = 1:3;
s.b = zeros(2,3);
s % a: [1 2 3]; b: [2x3 double]
for f = fieldnames(s)'
s.(f{1}) = s.(f{1})';
end
s % a: [3x1 double]; b: [3x2 double]
% Redefining f simplifies the indexing.
for f = fieldnames(s)'
f = f{1};
s.(f) = s.(f)';
end
s % back to a: [1 2 3]; b: [2x3 double]
データの配列があるとしましょう:
n = [1 2 3 4 6 12 18 51 69 81 ]
次に、次のように「foreach」できます。
for i = n, i, end
これにより、n のすべての要素がエコーされます (ただし、i をより興味深いものに置き換えることももちろん可能です!)
本日 (2 月 27 日) の時点で、MATLAB ファイル交換に新しい For-Each ツールボックスがあり、foreach
. foreach
は MATLAB 言語の一部ではありませんが、このツールボックスを使用すると、何が行われるかをエミュレートforeach
できます。
これがOPが本当に望んでいることだと思います:
array = -1:0.1:10
for i=1:numel(array)
disp(array(i))
end