MATLAB มี foreach หรือไม่ ถ้าเป็นเช่นนั้นมันจะทำงานอย่างไรถ้าข้อมูลพื้นฐานเปลี่ยนแปลง?


170

MATLAB มีโครงสร้าง foreach หรือไม่ ถ้าเป็นเช่นนั้นจะเกิดอะไรขึ้นถ้าข้อมูลพื้นฐานเปลี่ยนแปลง (เช่นถ้าวัตถุถูกเพิ่มเข้าไปในชุด)?

คำตอบ:


146

FOR FORของ MATLAB นั้นเป็นแบบคงที่ในธรรมชาติ คุณไม่สามารถแก้ไขตัวแปรลูประหว่างการวนซ้ำซึ่งแตกต่างจากโครงสร้างลูปfor (การเตรียมใช้งาน; เงื่อนไขการเพิ่มขึ้น)ในภาษาอื่น ซึ่งหมายความว่ารหัสต่อไปนี้จะพิมพ์ 1, 2, 3, 4, 5 เสมอโดยไม่คำนึงถึงค่าของ B

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

Btw, for-each loop ใน Java (และภาษาอื่น ๆ ที่เป็นไปได้) สร้างลักษณะการทำงานที่ไม่ระบุเมื่อโครงสร้างข้อมูลถูกแก้ไขในระหว่างการทำซ้ำ หากคุณต้องการแก้ไขโครงสร้างข้อมูลคุณควรใช้อินสแตนซ์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
สำหรับตัวอย่างที่ 1 ตรวจสอบให้แน่ใจว่าAเป็นเวกเตอร์แถวไม่ใช่เวกเตอร์คอลัมน์ ถ้าAเป็นเมทริกซ์แต่ละ k จะเป็นเวกเตอร์คอลัมน์จากเมทริกซ์นั้น ดังนั้น transpose ( A') หรือ vectorize ( A(:)') หากจำเป็น
yuk

3
-1 ฉันไม่คิดว่าโค้ดที่คล้าย Java ควรเป็นตัวเลือกแรกของคุณในการทำงานกับ Matlab ใน.mไฟล์
bobobobo

1
คำทักทายจากอนาคต เรามาพร้อมกับโซลูชันมากมายเพื่อแก้ไขปัญหาการตรวจสอบความถูกต้องของตัววนซ้ำ
Dmitry

89

ซัคถูกต้องเกี่ยวกับคำตอบที่ตรงกับคำถาม

ข้อสังเกตที่น่าสนใจคือลูปสองวงต่อไปนี้ไม่ทำงานเหมือนกัน:

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

ลูปแรกสร้างตัวแปรiที่เป็นสเกลาร์และวนซ้ำมันเหมือนกับ C สำหรับลูป โปรดทราบว่าหากคุณแก้ไขiในลูปเนื้อหาค่าที่แก้ไขจะถูกละเว้นดัง Zach กล่าว ในกรณีที่สอง Matlab จะสร้างอาร์เรย์ 10k-element จากนั้นมันจะเดินองค์ประกอบทั้งหมดของอาร์เรย์

สิ่งนี้หมายความว่าอะไร

for i=1:inf
  % do something
end

ทำงานได้ แต่

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

ไม่ (เพราะอันนี้จะต้องมีการจัดสรรหน่วยความจำที่ไม่มีที่สิ้นสุด) ดูบล็อกของ Lorenเพื่อดูรายละเอียด

นอกจากนี้โปรดทราบว่าคุณสามารถทำซ้ำผ่านอาร์เรย์เซลล์ได้


2
ใช่ฉันรู้สึกประหลาดใจกับเรื่องนี้เมื่อฉันวิ่งเข้าไปหามัน การเพิ่มประสิทธิภาพของอาร์เรย์นี้เกิดขึ้นจริงในหลายสถานที่ หากคุณใช้เครื่องหมายวงเล็บบางครั้งคุณจะเห็นคำเตือนประสิทธิภาพในตัวแก้ไข Matlab บอกคุณว่าคิดว่ามันสามารถเพิ่มประสิทธิภาพการจัดสรรอาเรย์ถ้าคุณให้มัน
Mr Fooz

ฉันได้ยินว่า Matlab มีการประเมินที่ขี้เกียจในขณะนี้ ถ้าไม่เรามีเทคโนโลยีที่จะนำมาใช้
Dmitry

19

MATLAB สำหรับการวนซ้ำนั้นจะช่วยให้มีความยืดหยุ่นอย่างมากรวมถึงฟังก์ชั่น นี่คือตัวอย่าง:

1) กำหนดดัชนีเริ่มต้นเพิ่มขึ้นและสิ้นสุด

for test = 1:3:9
   test
end

2) วนรอบเวกเตอร์

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

3) วนรอบสตริง

for test = 'hello'
   test
end

4) วนรอบอาร์เรย์เซลล์หนึ่งมิติ

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

5) วนรอบอาร์เรย์เซลล์สองมิติ

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

17

cellfunถ้าคุณกำลังพยายามที่จะห่วงมากกว่าอาร์เรย์เซลล์และนำบางสิ่งบางอย่างไปยังองค์ประกอบในเซลล์แต่ละตรวจสอบ นอกจากนี้ยังมีarrayfun, bsxfunและstructfunซึ่งอาจลดความซับซ้อนของโปรแกรมของคุณ


แม้ว่าจากประสบการณ์ผมจะบอกว่าการแสดงของพวกเขานั้นเท่ากันหรือแย่ที่สุดในการเขียน for-loop ดูดีกว่าและใครจะรู้ว่าพวกเขาอาจพัฒนาได้ในอนาคต

14

โอ! คำถามที่เรียบร้อย

Matlab's for loop ใช้เมทริกซ์เป็นอินพุตและวนซ้ำคอลัมน์ Matlab ยังจัดการทุกอย่างตามค่าจริง (ไม่มีการอ้างอิงผ่าน) ดังนั้นฉันคาดว่ามันจะถ่ายภาพอินพุตของ for-loop ดังนั้นมันจึงไม่เปลี่ยนรูป

นี่คือตัวอย่างที่อาจช่วยอธิบาย:

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

เมื่อวนซ้ำสตริงอาร์เรย์ของเซลล์ตัวแปรวนรอบ (ลองเรียกมันว่า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

นั่นแค่พิมพ์ 10 เพราะnumel(array)จำนวนองค์ประกอบในอาเรย์ บางทีคุณอาจหมายถึง1:numel(array)?
Kleist

จะfor i = -1:0.1:10; disp(i); end;ดีกว่าไหม
Oriol

4

ณ วันนี้ (27 กุมภาพันธ์) มีการใหม่สำหรับแต่ละกล่องบนไฟล์ MATLAB แลกเปลี่ยนforeachที่สำเร็จแนวคิดของ foreachไม่ได้เป็นส่วนหนึ่งของภาษา MATLAB แต่การใช้กล่องเครื่องมือนี้ทำให้เราสามารถเลียนแบบสิ่งที่foreachจะทำ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.