Apakah ada foreach di MATLAB? Jika demikian, bagaimana perilakunya jika data yang mendasarinya berubah?

171

Apakah ada struktur foreach di MATLAB? Jika demikian, apa yang terjadi jika data yang mendasarinya berubah (yaitu jika objek ditambahkan ke set)?

Tidur
sumber

Jawaban:

147

FOR loop MATLAB bersifat statis; Anda tidak dapat mengubah variabel loop antara iterasi, tidak seperti struktur loop untuk (inisialisasi; kondisi; kenaikan) dalam bahasa lain. Ini berarti bahwa kode berikut selalu mencetak 1, 2, 3, 4, 5 terlepas dari nilai B.

A = 1:5;

for i = A
    A = B;
    disp(i);
end

Jika Anda ingin dapat menanggapi perubahan dalam struktur data selama iterasi, loop WHILE mungkin lebih tepat --- Anda akan dapat menguji kondisi loop di setiap iterasi, dan mengatur nilai variabel loop ( s) sesuai keinginan:

n = 10;
f = n;
while n > 1
    n = n-1;
    f = f*n;
end
disp(['n! = ' num2str(f)])

Btw, untuk-setiap loop di Jawa (dan mungkin bahasa lain) menghasilkan perilaku yang tidak ditentukan ketika struktur data dimodifikasi selama iterasi. Jika Anda perlu mengubah struktur data, Anda harus menggunakan instance Iterator yang sesuai yang memungkinkan penambahan dan penghapusan elemen dalam koleksi yang Anda iterasi. Berita baiknya adalah bahwa MATLAB mendukung objek Java, sehingga Anda dapat melakukan sesuatu seperti ini:

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
Zach Scrivena
sumber
1
Jika B tidak terdefinisi, contoh pertama Anda tidak mencetak 1-5. Mencetak Undefined function or variable 'B'.
Kleist
3
Untuk contoh pertama, pastikan itu Aadalah vektor baris, bukan vektor kolom. Jika Asebuah matriks, setiap k akan menjadi vektor kolom dari matriks itu. Jadi, transpos ( A') atau vektorisasi ( A(:)') jika perlu.
yuk
3
-1 Saya tidak berpikir kode seperti Java harus menjadi pilihan pertama Anda untuk bekerja dengan Matlab dalam .mfile.
bobobobo
1
salam dari masa depan; kami datang dengan banyak solusi untuk masalah pembatalan iterator.
Dmitry
90

Zach benar tentang jawaban langsung untuk pertanyaan itu.

Catatan samping yang menarik adalah bahwa dua loop berikut tidak menjalankan yang sama:

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

Loop pertama membuat variabel iyang merupakan skalar dan iterates seperti C untuk loop. Perhatikan bahwa jika Anda memodifikasi idi badan loop, nilai yang diubah akan diabaikan, seperti kata Zach. Dalam kasus kedua, Matlab menciptakan array 10k-elemen, lalu berjalan semua elemen array.

Apa ini artinya itu

for i=1:inf
  % do something
end

bekerja, tapi

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

tidak (karena yang ini akan membutuhkan alokasi memori tak terbatas). Lihat blog Loren untuk detailnya.

Perhatikan juga bahwa Anda dapat beralih di atas array sel.

Tuan Fooz
sumber
2
Ya, saya terkejut tentang hal ini ketika saya bertemu dengannya. Optimalisasi array ini sebenarnya terjadi di banyak tempat. Jika Anda menggunakan notasi braket, kadang-kadang Anda akan melihat peringatan kinerja di editor Matlab yang memberi tahu Anda bahwa hal itu dapat mengoptimalkan alokasi array jika Anda membiarkannya.
Tuan Fooz
Saya mendengar Matlab memiliki evaluasi malas sekarang. Jika tidak, kami memiliki teknologi untuk mengimplementasikannya.
Dmitry
19

MATLAB untuk loop pada dasarnya memungkinkan fleksibilitas yang sangat besar, termasukKegunaan. Berikut beberapa contoh:

1) Tetapkan indeks awal, kenaikan, dan akhir

for test = 1:3:9
   test
end

2) Lingkaran di atas vektor

for test = [1, 3, 4]
   test
end

3) Lingkarkan melewati tali

for test = 'hello'
   test
end

4) Lingkarkan di atas larik sel satu dimensi

for test = {'hello', 42, datestr(now) ,1:3}
   test
end

5) Loop di atas array sel dua dimensi

for test = {'hello',42,datestr(now) ; 'world',43,datestr(now+1)}
   test(1)   
   test(2)
   disp('---')
end

6) Gunakan nama bidang array struktur

s.a = 1:3 ; s.b = 10  ; 
for test = fieldnames(s)'
   s.(cell2mat(test))
end
BHF
sumber
4
Dengan array sel, perhatikan bahwa itu akan beralih di atas kolom array sel.
Evgeni Sergeev
17

Jika Anda mencoba untuk mengulang larik sel dan menerapkan sesuatu ke setiap elemen dalam sel, periksa cellfun. Ada juga arrayfun,, bsxfundan structfunyang dapat menyederhanakan program Anda.

Loren
sumber
Namun, dari pengalaman saya akan mengatakan bahwa kinerja mereka sama atau terburuk untuk menulis for-loop, lebih baik cari, dan siapa tahu mereka mungkin membaik di masa depan.
14

ooh! pertanyaan rapi.

Matlab's for loop mengambil matriks sebagai input dan beralih ke kolomnya. Matlab juga menangani hampir semua hal berdasarkan nilai (tanpa pass-by-reference) jadi saya berharap bahwa ia mengambil snapshot dari input for-loop sehingga tidak dapat diubah.

inilah contoh yang dapat membantu menggambarkan:

>> 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
Jason S
sumber
7

Saat mengulangi array sel string, variabel loop (sebut saja f) menjadi array sel elemen tunggal. Harus menulis di f{1}mana-mana menjadi membosankan, dan memodifikasi variabel loop memberikan solusi yang bersih.

% 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]

sumber
5

Katakanlah Anda memiliki array data:

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

maka Anda bisa 'pramuka' seperti ini:

for i = n, i, end

Ini akan menggemakan setiap elemen dalam n (tapi tentu saja mengganti i dengan hal-hal yang lebih menarik juga mungkin!)

Skidder
sumber
4

Saya pikir inilah yang benar-benar diinginkan OP:

array = -1:0.1:10

for i=1:numel(array)
    disp(array(i))
end
Tirth
sumber
Itu hanya mencetak 10 karena numel(array)jumlah elemen dalam array. mungkin maksudmu 1:numel(array)?
Kleist
Tidak for i = -1:0.1:10; disp(i); end;akan lebih baik?
Oriol