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

Zach 对这个问题的直接回答是正确的。

一个有趣的旁注是,以下两个循环的执行方式不同:

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 的博客

另请注意,您可以迭代元胞数组。

于 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) 循环一维元胞数组

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
于 2013-10-05T11:08:55.887 回答
19

如果您尝试循环遍历单元格数组并将某些内容应用于单元格中的每个元素,请查看cellfun. 还有arrayfun, bsxfun,structfun可以简化你的程序。

于 2009-06-26T11:25:31.670 回答
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

我认为这是OP真正想要的:

array = -1:0.1:10

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

截至今天(2 月 27 日),MATLAB File Exchange 上有一个新的 For-Each 工具箱,它实现了foreach. foreach不是 MATLAB 语言的一部分,但使用此工具箱使我们能够模拟foreach将要做什么。

于 2015-02-27T16:12:52.507 回答