전체 페이지뷰

2018년 10월 24일 수요일

루프(while과 for), switch

루프 


while


while (condition) {
    // loop body
    // ...
}

의 문법을 가지고 조건이 true인 동안 loop body가 수행됩니다.

예를 들면 
let i = 0;
while (i < 3) { // shows 0, then 1, then 2
  alert( i );
  i++;
}
cs
이런 것인데, 

조건문 속에는 비교문 뿐만 아니라 변수나 표현식도 올 수 있습니다.

아래의 예에서는 while ( i != 0 ) 을 대신해서 while(i)가 사용되었습니다.
let i = 3;
while (i) { // i가 0이 되면 false가 되어 루프 종료
  alert( i );
  i--;
}
cs

더 간략하게는
let i = 3;
while (i) alert(i--);
cs
로도 쓸 수 있습니다.


do...while

조건문이 뒤로 가서 최소한 한번은 loop body가 실행됩니다.

do {
    // loop body
} while (condition)

예)
let i = 0;
do {
  alert( i );
  i++;
while (i < 3);
cs


for

가장 많이 사용되는 루프입니다.

for ( begin; condition; step ) {
    // loop body
}

예)
for (let i = 0; i < 3; i++) { // shows 0, then 1, then 2
  alert(i);
}
cs

let이 들어간 이유는 이미 선언되었던 변수가 아니라 루프에서 쓰기 위한 것을 새로 선언하기 위해서입니다.

아래의 두 개를 비교해 보시기 바랍니다.
for (let i = 0; i < 3; i++) {
  alert(i); // 0, 1, 2
}
alert(i); // error, no such variable
cs

let i = 0;
 
for (i = 0; i < 3; i++) { // use an existing variable
  alert(i); // 0, 1, 2
}
 
alert(i); // 3, visible, because declared outside of the loop
cs



생략

for 루프 구문 내의 어느 부분일지라도 생략이 가능합니다(;은 생략 불가).

초기식이 생략된 경우
let i = 0// we have i already declared and assigned
 
for (; i < 3; i++) { // no need for "begin"
  alert( i ); // 0, 1, 2
}
cs

증감식이 생략된 경우
let i = 0;
 
for (; i < 3;) {
  alert( i++ );
}
cs

무한 루프 시에는 모두 생략 가능합니다.
for (;;) {
  // repeats without limits
}
cs


loop 빠져나오기

루프를 도중 임의의 순간에 빠져나오고 싶을 땐 break를 사용합니다.

let sum = 0;
 
while (true) {
 
  let value = +prompt("Enter a number"'');
 
  if (!value) break// (*)
 
  sum += value;
 
}
alert'Sum: ' + sum );
cs

위의 코드에서는 유저가 입력을 생략하거나 빈 문자열을 넣었을 떄 (*)줄의 break가 활성화되어 콘트롤을 루프 바로 다음 줄인 alert로 넘겨줍니다.


다음 iteration으로 넘어가기 : continue

continuebreak의 작은 버전이라고 할 수 있습니다. 루프를 완전히 빠져나가는 대신 다음 조건 순서로 넘어가 iteration을 계속하게 합니다.

홀수만 출력하는 다음의 코드를 봅시다.
for (let i = 0; i < 10; i++) {
 
  // if true, skip the remaining part of the body
  if (i % 2 == 0continue;
 
  alert(i); // 1, then 3, 5, 7, 9
}
cs


삼항연산자는 break/continue를 허용하지 않습니다.

예를 들어 다음과 같은 코드를
if (i > 5) {
  alert(i);
else {
  continue;
}
cs

다음과 같이 바꿀 수 없습니다.
(i > 5) ? alert(i) : continue;
cs

이 코드는 syntax error를 일으킬 겁니다.


break/continue의 라벨

때로 여러 개 중첩된 루프를 한번에 빠져나와야할 때가 있습니다.

i와 j의 루프로 이루어진 다음 코드를 봅시다.
for (let i = 0; i < 3; i++) {
 
  for (let j = 0; j < 3; j++) {
 
    let input = prompt(`Value at coords (${i},${j})`, '');
 
    // what if I want to exit from here to Done (below)?
 
  }
}
 
alert('Done!');
cs

유저가 입력을 취소하면 두개의 for 루프를 한번에 빠져나와야 하는데, 이 경우 break를 사용하면 안쪽 루프만을 빠져나올 뿐입니다.

이 경우 루프에 라벨을 붙여 빠져나오는 수준을 지정할 수 있습니다.

문법은
labelName: for ( ... ) {
    ...
}
입니다.

사용 예를 봅시다.
outer: for (let i = 0; i < 3; i++) {
 
  for (let j = 0; j < 3; j++) {
 
    let input = prompt(`Value at coords (${i},${j})`, '');
 
    // if an empty string or canceled, then break out of both loops
    if (!input) break outer; // (*)
 
    // do something with the value...
  }
}
alert('Done!');
cs

바깥쪽 루프에 outer라는 라벨을 지정해서 break로 한번에 빠져나오게 되었습니다.

continue의 경우도 바찬가지로 라벨을 지정할 수 있습니다.


break는 goto가 아닙니다

따라서 코드 내의 임의의 위치로 이동시키는 역할을 하지 않으며, 단지 루프에서만 사용 가능합니다.



switch

문법

한 개 이상의 case 블록과 선택적인 default로 구성됩니다.
switch(x) {
  case 'value1':  // if (x === 'value1')
    ...
    [break]
 
  case 'value2':  // if (x === 'value2')
    ...
    [break]
 
  default:
    ...
    [break]
}
cs

예를 들어 보겠습니다.
let a = 2 + 2;
 
switch (a) {
  case 3:
    alert'Too small' );
    break;
  case 4:
    alert'Exactly!' );
    break;
  case 5:
    alert'Too large' );
    break;
  default:
    alert"I don't know such values" );
}
cs

첫 case인 3과 비교하여 맞지 않으므로 다음 case 4로 넘어갑니다. a는 4이므로 "Exactly!'를 출력하고 break로 switch문을 빠져나갑니다.

만약, break문이 없다면 값 체크 없이 아래의 구문들을 모두 실행하게 됩니다.

let a = 2 + 2;
 
switch (a) {
  case 3:
    alert'Too small' );
  case 4:
    alert'Exactly!' );
  case 5:
    alert'Too big' );
  default:
    alert"I don't know such values" );
}
cs

이 코드의 실행결과는
alert'Exactly!' );
alert'Too big' );
alert"I don't know such values" );
cs
와 같아집니다.

switch/case의 인자로는 값뿐만 아니라 표현식도 올 수 있습니다.

let a = "1";
let b = 0;
 
switch (+a) {
  case b + 1:
    alert("this runs, because +a is 1, exactly equals b+1");
    break;
 
  default:
    alert("this doesn't run");
}
cs
를 살펴보면,

+a로 문자 1이 숫자 1로 변환되고, b+1의 계산결과인 1과 같아져서 첫 문장이 출력됩니다.


case 묶기

case의 몇 경우들이 같은 코드를 공요해야할 경우 다음과 같이 묶어질 수 있습니다.
let a = 2 + 2;
 
switch (a) {
  case 4:
    alert('Right!');
    break;
 
  case 3:                    // (*) grouped two cases
  case 5:
    alert('Wrong!');
    alert("Why don't you take a math class?");
    break;
 
  default:
    alert('The result is strange. Really.');
}
cs

break가 없으면 다음 코드가 실행된다는 점을 이용하여 3, 5의 경우에 같은 코드를 수행하도록 만들었습니다.


Type은 일치해야 합니다

 switch문의 비교는 엄격한 비교이기 때문에 입력된 값의 타입도 같아야 합니다.

let arg = prompt("Enter a value?")
switch (arg) {
  case '0':
  case '1':
    alert'One or zero' );
    break;
 
  case '2':
    alert'Two' );
    break;
 
  case 3:
    alert'Never executes!' );
    break;
  default:
    alert'An unknown value' )
}
cs

이 경우 3이 문자가 아닌 숫자이므로 만약 3이 입력되었다면 default 값이 출력됩니다.

댓글 없음:

댓글 쓰기