MATLAB에 foreach가 있습니까? 그렇다면 기본 데이터가 변경되면 어떻게 작동합니까?


170

MATLAB에 foreach 구조가 있습니까? 그렇다면 기본 데이터가 변경되면 (즉, 객체가 세트에 추가 된 경우) 어떻게됩니까?

답변:


146

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

1
B가 정의되어 있지 않으면 첫 번째 예제는 1-5를 인쇄하지 않습니다. 인쇄합니다 Undefined function or variable 'B'.
Kleist

3
첫 번째 예 A에서는 열 벡터가 아니라 행 벡터 인지 확인하십시오 . 경우 A매트릭스이며, 각각 k는 해당 행렬의 열 벡터가 될 것이다. 따라서 필요한 경우 transpose ( A') 또는 벡터화 ( A(:)')하십시오.
yuk

3
-1 Java와 같은 코드가 파일 에서 Matlab을 사용하기위한 첫 번째 선택 방법이라고 생각 하지 않습니다.m .
bobobobo

1
미래의 인사; 우리는 반복자 무효화 문제에 대한 많은 솔루션을 제공합니다.
Dmitry

89

Zach은 그 질문에 대한 직접적인 대답에 대해 옳습니다.

흥미로운 참고 사항은 다음 두 루프가 동일하게 실행되지 않는다는 것입니다.

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

첫 번째 루프 i는 스칼라 인 변수 를 작성 하고 C for 루프처럼 반복합니다. 참고 수정할 경우 것으로 i자크가 말한대로 루프 본문에 수정 된 값은 무시됩니다. 두 번째 경우 Matlab은 10k 요소 배열을 만든 다음 배열의 모든 요소를 ​​걷습니다.

이것이 의미하는 것은

for i=1:inf
  % do something
end

작동하지만

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

(이것은 무한 메모리를 할당해야하기 때문에) 아닙니다. 자세한 내용은 Loren의 블로그 를 참조하십시오.

또한 셀형 배열을 반복 할 수 있습니다.


2
그래, 나는 그것을 만났을 때 이것에 대해 놀랐다. 이러한 배열 최적화는 실제로 여러 곳에서 이루어집니다. 대괄호 표기법을 사용하는 경우 Matlab 편집기에 성능 경고가 표시되어 배열 할당을 허용하면 최적화 할 수 있다고 생각하는 경우가 있습니다.
Mr Fooz

Matlab에 게으른 평가가 있다고 들었습니다. 그렇지 않다면이를 구현할 기술이 있습니다.
Dmitry

19

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) 1 차원 셀 어레이에 루프

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

5) 2 차원 셀 어레이에 루프

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, bsxfunstructfun프로그램을 단순화 할 수있다.


그러나 경험상 나는 그들의 성능이 for-loop를 작성하고 더 나은 모습을 보이는 것과 동등하거나 최악이라고 말할 것입니다.

14

아! 깔끔한 질문.

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

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  ]

다음과 같이 '예측'할 수 있습니다.

for i = n, i, end

이것은 n의 모든 요소를 ​​에코합니다 (그러나 i를 더 흥미로운 것들로 대체하는 것도 가능합니다!)


4

OP가 실제로 원하는 것입니다.

array = -1:0.1:10

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

numel(array)배열의 요소 수 이므로 10을 인쇄합니다 . 아마도 당신은 의미 1:numel(array)?
Kleist

for i = -1:0.1:10; disp(i); end;더 좋지 않을까요 ?
Oriol

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.