MATLABにはforeachがありますか?もしそうなら、基礎となるデータが変更された場合、どのように動作しますか?


170

MATLABにforeach構造はありますか?もしそうなら、基礎となるデータが変更された場合(つまり、オブジェクトがセットに追加された場合)はどうなりますか?

回答:


146

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

1
Bが未定義の場合、最初の例では1〜5が出力されません。印刷しUndefined function or variable 'B'ます。
Kleist

3
最初の例でAは、それが列ベクトルではなく行ベクトルであることを確認してください。Aが行列の場合、各kはその行列の列ベクトルになります。したがって、必要に応じて、転置(A')またはベクトル化(A(:)')します。
yuk

3
-1 Javaのようなコードは、Matlabをファイルで操作するための最初の選択方法ではないと思い.mます。
bobobobo 2012年

1
未来からのご挨拶。イテレータの無効化問題に対する多くの解決策が用意されています。
Dmitry

89

ザックは質問への直接の答えについて正しいです。

興味深い補足として、次の2つのループは同じようには実行されません。

for i=1:10000
  % do something
end
for i=[1:10000]
  % do something
end

最初のループはiスカラーの変数を作成し、Cのforループのように反復します。iループ本体で変更すると、Zachが言うように、変更された値は無視されることに注意してください。2番目のケースでは、Matlabは10k要素の配列を作成し、配列のすべての要素を調べます。

これが意味することは

for i=1:inf
  % do something
end

動作しますが

for i=[1:inf]
  % do something
end

(これは無限のメモリを割り当てる必要があるためです)。詳細については、ローレンのブログを参照してください。

また、セル配列を反復処理できることにも注意してください。


2
ええ、私はそれに遭遇したときにこれに驚きました。この配列の最適化は、実際には多くの場所で行われます。ブラケット表記を使用する場合、Matlabエディターにパフォーマンス警告が表示され、可能であれば配列の割り当てを最適化できると思われることが通知されます。
Fooz氏、2009年

Matlabは遅延評価を今持っていると聞いています。そうでない場合、私たちはそれらを実装する技術を持っています。
Dmitry

19

MATLAB forループは基本的に、機能性。ここにいくつかの例があります:

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次元セル配列をループする

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

4
セル配列では、セル配列のを反復処理することに注意してください。
Evgeni Sergeev 2014

17

セル配列をループしてセルの各要素に何かを適用しようとしている場合は、をチェックしてくださいcellfun。そこもだarrayfunbsxfunと、structfunあなたのプログラムを簡素化することがあります。


ただし、経験から言うと、彼らのパフォーマンスはforループの記述と同等か最悪であり、見栄えがよく、将来的には改善される可能性があることを誰が知っていますか。

14

おお!きちんとした質問。

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

7

文字列のセル配列を反復処理すると、ループ変数(itとしましょう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]

5

データの配列があるとしましょう:

n = [1    2   3   4   6   12  18  51  69  81  ]

その後、次のように「foreach」できます。

for i = n, i, end

これにより、nのすべての要素がエコーされます(ただし、iをより興味深いものに置き換えることももちろん可能です!)


4

これはOPが本当に望んでいることだと思います:

array = -1:0.1:10

for i=1:numel(array)
    disp(array(i))
end

numel(array)配列の要素の数は10なので、これは10を出力します。もしかして1:numel(array)
Kleist

for i = -1:0.1:10; disp(i); end;良いと思いませんか?
Oriol

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.