MATLAB中是否有foreach结构?如果是这样,如果基础数据发生变化(即对象是否添加到集合中)会发生什么?
MATLAB的FOR循环本质上是静态的; 你不能在迭代之间修改循环变量,这与其他语言中的for(初始化;条件;增量)循环结构不同.这意味着无论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
扎克对这个问题的直接答案是正确的.
一个有趣的旁注是以下两个循环不执行相同的操作:
for i=1:10000 % do something end for i=[1:10000] % do something end
第一个循环创建一个变量i
,它是一个标量,它像C for循环一样迭代它.请注意,如果i
在循环体中修改,修改后的值将被忽略,如Zach所说.在第二种情况下,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)在一维单元阵列上循环
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
如果您尝试循环单元格数组并对单元格中的每个元素应用某些内容,请检查cellfun
.还有arrayfun
,bsxfun
和structfun
它可以简化程序.
哦!整洁的问题.
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 ]
然后你可以像这样"预先"它:
for i = n, i, end
这将回显n中的每个元素(但当然也可以用更有趣的东西替换i!)