MATLAB 中是否有 foreach? 如果有,当底层数据发生变化时它是如何工作的?

MATLAB 中有 foreach 结构吗?如果是这样,那么如果底层数据发生变化(例如,如果对象被添加到集合中)会发生什么?

177773 次浏览

问得好。

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

MATLAB 的 为了循环本质上是静态的; 与其他语言中的 For (初始化; 条件; 增量)循环结构不同,您不能在迭代之间修改循环变量。这意味着下面的代码总是打印1,2,3,4,5,而不管 B 的值是多少。

A = 1:5;


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

如果您希望能够在迭代期间响应数据结构的变化,那么使用 < strong > WHILE loop可能更合适——-- 您将能够在每次迭代时测试循环条件,并根据您的愿望设置循环变量的值:

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

顺便说一句,当在迭代期间修改数据结构时,每个人循环 用爪哇语(可能还有其他语言)会产生未指定的行为。如果需要修改数据结构,应该使用适当的 翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳实例,该实例允许在迭代的集合中添加和删除元素。好消息是 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 的博客了解详细信息。

还要注意,可以在单元格数组上迭代。

如果您试图在单元格数组上循环并对单元格中的每个元素应用一些内容,请查看 cellfun。还有 arrayfunbsxfunstructfun,它们可以简化你的程序。

当迭代字符串的单元格数组时,循环变量(我们称之为 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 也是可能的!)

我认为这才是观察所真正想要的:

array = -1:0.1:10


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

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

截至今天(2月27日) ,在 MATLAB 文件交换中有一个新的 For-Each 工具箱实现了 foreach的概念。foreach不是 MATLAB 语言的一部分,但是使用这个工具箱使我们能够模拟 foreach会做什么。