Есть ли в MATLAB foreach? Если да, то как он себя ведет при изменении базовых данных?

Есть ли в MATLAB структура foreach? Если да, то что произойдет, если базовые данные изменятся (т. Е. Если в набор добавлены объекты)?


person Kip    schedule 02.01.2009    source источник


Ответы (9)


Цикл MATLAB FOR статичен по своей природе; вы не можете изменять переменную цикла между итерациями, в отличие от структуры цикла for (инициализация; условие; приращение) в других языках. Это означает, что следующий код всегда печатает 1, 2, 3, 4, 5 независимо от значения B.

A = 1:5;

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

Если вы хотите иметь возможность реагировать на изменения в структуре данных во время итераций, используйте WHILE loop может быть более подходящим - вы сможете проверять условие цикла на каждой итерации и устанавливать значение переменных цикла, как вы желание:

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

Кстати, цикл для каждого в 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
person Zach Scrivena    schedule 02.01.2009
comment
Если B не определено, ваш первый пример не печатает 1-5. Он печатает Undefined function or variable 'B'. - person Kleist; 07.12.2011
comment
В первом примере убедитесь, что A - это вектор-строка, а не вектор-столбец. Если A - матрица, каждое k будет вектором-столбцом из этой матрицы. Итак, при необходимости транспонируйте (A') или векторизуйте (A(:)'). - person yuk; 08.12.2011
comment
-1 Я не думаю, что Java-подобный код должен быть вашим первым способом работы с Matlab в .m файлах. - person bobobobo; 23.10.2012
comment
привет из будущего; у нас есть множество решений проблемы недействительности итератора. - person Dmitry; 12.12.2016

Зак прав насчет прямого ответа на вопрос.

Интересное замечание заключается в том, что следующие два цикла не выполняются одинаково:

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

Первый цикл создает переменную i, которая является скаляром, и выполняет ее итерацию, как цикл C for. Обратите внимание, что если вы измените i в теле цикла, измененное значение будет проигнорировано, как говорит Зак. Во втором случае Matlab создает массив из 10 тыс. Элементов, а затем просматривает все элементы массива.

Это означает, что

for i=1:inf
  % do something
end

работает, но

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

нет (потому что для этого потребуется выделить бесконечную память). Подробности см. В блоге Лорен.

Также обратите внимание, что вы можете перебирать массивы ячеек.

person Mr Fooz    schedule 03.01.2009
comment
Да, я был удивлен этим, когда столкнулся с этим. Такая оптимизация массивов действительно имеет место во многих местах. Если вы используете скобочную нотацию, иногда вы увидите предупреждения о производительности в редакторе Matlab, говорящие о том, что он думает, что может оптимизировать распределение массива, если вы это позволите. - person Mr Fooz; 03.01.2009
comment
Я слышал, что у Matlab сейчас ленивая оценка. В противном случае у нас есть технологии для их реализации. - person Dmitry; 12.12.2016

Цикл 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
person BHF    schedule 05.10.2013
comment
Обратите внимание, что с массивом ячеек выполняется итерация по столбцам массива ячеек. - person Evgeni Sergeev; 06.02.2014

Если вы пытаетесь перебрать массив ячеек и применить что-то к каждому элементу в ячейке, проверьте cellfun. Также есть arrayfun, bsxfun и structfun, которые могут упростить вашу программу.

person Loren    schedule 26.06.2009
comment
хотя по опыту я бы сказал, что их производительность равна или хуже, чем при написании цикла for, хотя выглядит лучше, и кто знает, что они могут улучшиться в будущем. - person ; 19.03.2012

ох! аккуратный вопрос.

Цикл for в Matlab принимает матрицу в качестве входных данных и выполняет итерацию по ее столбцам. 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
person Jason S    schedule 02.01.2009

При итерации по массивам ячеек строк переменная цикла (назовем ее 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]
person Community    schedule 28.07.2009

Допустим, у вас есть массив данных:

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

тогда вы можете выполнить его "foreach" следующим образом:

for i = n, i, end

Это будет отражать каждый элемент в n (но, конечно, также можно заменить i на более интересные вещи!)

person Skidder    schedule 27.10.2011

Я думаю, это то, чего действительно хочет ОП:

array = -1:0.1:10

for i=1:numel(array)
    disp(array(i))
end
person tirth    schedule 28.10.2011
comment
Это просто выводит 10, поскольку numel(array) - это количество элементов в массиве. может ты имел ввиду 1:numel(array)? - person Kleist; 07.12.2011
comment
Разве for i = -1:0.1:10; disp(i); end; не было бы лучше? - person Oriol; 13.10.2013

С сегодняшнего дня (27 февраля) появился новый набор инструментов для каждого. в MATLAB File Exchange, который реализует концепцию foreach. foreach не является частью языка MATLAB, но использование этого набора инструментов дает нам возможность имитировать то, что foreach будет делать.

person Dang Khoa    schedule 27.02.2015