자바스크립트/바닐라 JS

[자바스크립트] TIL8 : 반복문의 종류와 구조 / 객체의 특성과 배열의 요소 순회를 위한 반복문 활용

charlie-lyc 2021. 4. 14. 02:20
728x90
반응형

반복문(Loop)

반복문에는 아래와 같이 세 가지 정도의 종류가 있으며 겉보기에 구조가 다르지만, 일반적으로 사용되는 코딩 패턴은 모두 다 초기화, 조건식, 반복자 증가, 명령의 네 가지 구문을 공통적으로 포함하고 있습니다.. 

 

□ For 반복문

for ( <initializing>; <condition>; <increment> ) {
  // <execution>
}

 

주로 사용하는 반복문 형태로 초기화, 조건식, 반복자 증가의 구문이 ( )안에 연속해서 들어가고, { } 블럭 안에는 명령 구문이 위치합니다. 코드의 실행은 먼저 초기화가 이루어진 다음, 조건식을 만족할 경우에 명령구문이 실행되고, 그 후에 반복자가 증가됩니다. 그런 다음 다시 조건식의 결과가 참인지 확인하여 참일 경우에 명령 구문도 한번 더 실행되는 순서로 진행되는데, 조건식을 만족하지 않을 때까지 계속됩니다. 참고로 반복자는 증가만 하는 것이 아니며 초기화와 조건식에 따라 다릅니다.

 

 While 반복문

<initializing>
while ( <condition> ) {
  // <execution>
  // <increment>
}

 

{ } 블럭 밖에서 초기화가 이루어지고, ( ) 안의 조건식을 만족할 경우에 { } 블럭 내의 명령을 실행하며, 그런 다음에 반복자가 증가됩니다. 이때 반복자가 증가되는 시점은 명령의 실행 이전이 될 수도 있고 이후가 될 수도 있습니다.  

 

 

 Do While 반복문

<initializing>
do {
  // <execution>
  // <increment>
} while ( <condition> )

 

{ } 블럭 밖에서 초기화가 이루어지고, 일단 먼저 { } 블럭 내의 명령을 실행한 다음에, ( ) 안의 조건식을 만족할 경우 반복문이 계속 진행되고 그렇지 않을 경우에는 반복문이 더 이상 진행되지 않습니다. While 반복문과 마찬가지로 반복자가 증가되는 시점은 명령의 실행 이전이 될수도 있고 이후가 될 수도 있습니다.

 


반복문 종류별 예시

/* For Loop */
for (let i = 0; i < 6; i++) {
  console.log('Number ' + i);
}

/* While Loop */
let i = 0;
while (i < 6) {
  console.log("Number " + i);
  i++;
}

/* Do While Loop */
let j = 0;
do {
  console.log("Number " + j);
  j++;
} while (j < 6);

let k = 100;
do {
  console.log("Number " + k);
  k++;
} while (k < 6);

 

위와 같이 세 가지 종류의 반복문을 구조의 특성을 살려 간단히 구현해보면 아래와 같은 결과를 확인할 수 있습니다.  

 

 

For 반복문과 While 반복문은 조건식을 먼저 진행하여 참인 조건하에서 명령을 실행하는 패턴이지만, Do While 반복문은 일단 처음에는 실행을 먼저 하고 다음 반복부터 조건식을 따르는 것에 유의하기 바랍니다. 

 


 continue 와 break 이용

/* General Loop */
for (let i = 0; i < 6; i++) {
  if (i === 2) {
    console.log("2 is my favorite number.");
  }
  console.log("Number " + i);
}

/* Loop with continue */
for (let i = 0; i < 6; i++) {
  if (i === 2) {
    console.log("2 is my favorite number.");
    continue;
  }
  console.log("Number " + i);
}

/* Loop with break */
for (let i = 0; i < 6; i++) {
  if (i === 2) {
    console.log("2 is my favorite number.");
    break;
  }
  console.log("Number " + i);
}

 

반복문을 제어하기 위해 { } 블럭 내에서는 주로 If 조건문을 많이 사용하며, 그 외에 반복문과 함께 자주 사용되는 코드에는 continue; 와 break; 가 있습니다.

아래의 결과에서 보다시피 continue; 코드는 이후의 { } 블럭 내 실행을 건너뛰고 다음 반복으로 넘어가라는 명령이고, break; 코드는 실행을 멈추고 반복문을 벗어나라는 명령입니다.  

 

 


반응형

 

▣ 배열의 요소와 객체의 특성 순회

 


 For Of 반복문

for (const <element> of <array>) {
  // <execution>
}

 

일반적으로 배열의 길이('length' property)를 알고 있다면, For 반복문을 이용하여 모든 요소를 순회할 수 있습니다. 반면에 For Of 반복문을 사용하면 초기화, 배열의 길이를 포함하는 조건식, 반복자 증가의 구문을 작성하지 않고 간략하게 반복문을 나타낼 수 있어 편리합니다.

 

/** 
 * Traversing through Array's Elements 
 */
 
const cars = ["Tesla", "Renault", "Volvo", "Volkswagen"];

/* For : statement */
for (let i = 0; i < cars.length; i++) {
  console.log(cars[i]);
}

/* For Of : statement*/
for (const car of cars) {
  console.log(car);
}

 

위의 코드의 실행 결과는 아래와 같습니다.

 

 


 반복문 내장 배열 메서드

한편, 배열 객체에는 배열의 모든 요소를 순회하면서 필요한 명령을 수행할 수 있도록 반복문이 내장된 배열 메서드들이 있습니다. 이 메서드들은 기본적으로 반복문을 포함하고 있기 때문에 복잡한 연산을 간단하게 나타낼 수 있어 유용합니다. 그리고 반복문이 내장된 배열 메서드들은 공통적으로 함수를 인자로 가집니다.

 

 

 forEach()

 

forEach(function ( <currentValue>, <index>, <array> ) {
  // <execution>
});

 

배열 내의 요소들을 순회하면서 명령을 반복적으로 실행합니다. 기존의 For 반복문을 간략화한 형태라고 볼 수 있습니다.

 

 

 map()

 

const newArray = map(function ( <currentValue>, <index>, <array> ) {
  // return <element> for newArray, after <execution>
});

 

배열 내의 요소들을 순회하면서 명령을 반복적으로 실행하되, 각 요소에 대한 결과 값들을 모두 모아 새로운 배열로 반환합니다. 즉 map() 메서드의 실행을 통해 반환되는 결과는 배열의 형태입니다.

 

 

 filter()

 

const newArray = filter(function ( <currentValue>, <index>, <array> ) {
  // return <element> for newArray, if true
});

 

배열 내의 요소들을 순회하면서 조건식을 만족하는 요소들만 모아 새로운 배열로 반환합니다. 기능적으로 map()과 유사하지만 명령을 실행하느냐 아니면 참 또는 거짓을 판명하느냐의 차이가 있습니다.

 

 

 reduce()

 

const result = reduce(function ( <accumulator>, <currentValue>, <index>, <array> ) {
  // return <accumulator> for result, after <execution>
}, <initialValue> );

 

사실상 앞서 설명한 반복문이 내장된 배열 메서드 모두를 아우를 수 있는 메서드입니다. 사용법이 복잡하고 까다로운 것 같지만 제대로 활용할 수 있게 된다면 정말 유용한 메서드입니다. 누산기(Accumulator)라는 개념이 적용되어 길이가 긴 배열 형태의 데이터를 대상으로 압축, 요약할 수 있는 명령(합계, 평균 구하기 등)을 쉽게 구현할 수 있습니다.

특히, 누산기의 초기값(initialValue)을 설정할 수 있는데, 예를 들어 0을 시작 값으로 설정하여 누적 갯수를 구하거나 혹은 빈 배열([ ])을 시작 값으로 설정하여 최종 결과를 배열의 형태로 반환할 수 있습니다.

초기값 설정은 메서드의 실행 결과를 변수에 담고자 할 때 발생할 수 있는 에러 또는 undefined를 방지합니다. 그리고 시작 값이 별도로 정해지지 않을 경우에는 대상이 되는 배열의 첫 번째 요소가 시작 값으로 설정됩니다.

 


배열의 요소 순회 예시

/** 
 * Traversing through Array's Elements
 */
 
/* forEach() : method */
const cars = ["Tesla", "Renault", "Volvo", "Volkswagen"];
cars.forEach(function (car, index) {
  console.log(`${index} : ${car}`);
});

/* map() : method */
const users = [
  { id: 1, name: "Pete" },
  { id: 2, name: "Jerry" },
  { id: 3, name: "Ethan" }
];
const ids = users.map(function (user) {
  return user.id;
});
console.log(ids);
const names = users.map(function (user) {
  return user.name;
});
console.log(names);

/* filter() : method */
const result = users.filter(function (user) {
  return user.id < 3;
});
console.log(result);

/* reduce() : method */
const counter = users.reduce(function (acc, val) {
  if (val.id < 3) {
    return acc + 1;
  }
  return acc;
}, 0);
console.log(counter);

 

위의 코드와 아래의 실행 결과를 살펴보면, forEach() 를 이용하여 cars 배열의 모든 요소를 순회하면서 인덱스 값과 자동차 제조사를 콘솔에 출력하였고, map() 을 이용해서 users 배열 내의 모든 객체를 순회하면서 아이디 또는 이름을 각각 모아 배열로 반환하였으며, filter() 를 이용해서는 users 배열 내의 객체 중에서 아이디 값이 3보다 작은 경우의 객체만 골라 배열로 반환하였습니다. 마지막으로 reduce() 를 이용하여 users 배열 내의 객체 중에서 아이디 값이 3보다 작은 사용자들의 인원수를 구하여 결과로 반환하였습니다.

 

 


 For In 반복문

for (const <property> in <object>) {
  // <execution>
}

 

배열과 마찬가지로 객체 또한 모든 특성들의 갯수를 알고 있다면, For 반복문을 이용하여 순회할 수 있습니다. 반면에 For In 반복문을 사용하면 초기화, 특성의 갯수를 포함하는 조건식, 반복자 증가의 구문을 작성하지 않고 간략하게 반복문을 나타낼 수 있어 편리합니다.

 

※ 참고로 객체를 구성하고 있는 특성들의 개수를 알 수 있는 코드는 아래와 같습니다.

 

Object.keys( <object> ).length;

 


 객체의 특성 순회 예시

/**
 * Traversing through Object's Properties
 */

const user = {
  firstName: "John",
  lastName: "Doe",
  age: 30,
};

/* For : statement */
for (let i = 0; i < Object.keys(user).length; i++) {
  console.log(`${Object.keys(user)[i]} : ${user[Object.keys(user)[i]]}`);
}

/* For In : statement */
for (const key in user) {
  console.log(`${key} : ${user[key]}`);
}

 

위의 코드와 아래의 결과를 살펴보면, 객체의 특성을 순회할 때 For In 반복문이 For 반복문 보다 가독성이 높음을 파악할 수 있습니다.

 

 


 

728x90
반응형