177

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

4

9 に答える 9

150

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
于 2009-01-02T22:40:09.730 に答える
92

ザックは、質問に対する直接的な答えについて正しいです。

興味深いことに、次の 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 のブログを参照してください。

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

于 2009-01-03T04:43:42.630 に答える
20

基本的に、 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 次元 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
于 2013-10-05T11:08:55.887 に答える
15

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

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
于 2009-01-02T21:38:21.303 に答える
7

文字列のセル配列を反復処理する場合、ループ変数 ( と呼びましょう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]
于 2009-07-28T19:55:00.233 に答える
5

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

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

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

for i = n, i, end

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

于 2011-10-27T13:05:55.010 に答える
4

本日 (2 月 27 日) の時点で、MATLAB ファイル交換に新しい For-Each ツールボックスがありforeach. foreachは MATLAB 言語の一部ではありませんが、このツールボックスを使用すると、何が行われるかをエミュレートforeachできます。

于 2015-02-27T16:12:52.507 に答える
4

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

array = -1:0.1:10

for i=1:numel(array)
    disp(array(i))
end
于 2011-10-28T02:49:37.497 に答える