본문 바로가기
Programming/JavaScript

반복문 for, while, forEach, map - [Javascript 입문 _9]

by Muko 2020. 4. 15.

이번 포스팅은 반복문에 대해서 이야기해보려고 합니다.

친구들이랑 얘기하다보면, 혹은 인터넷 커뮤니티 글들을 보다보면 공대 출신 혹은 프로그래머 출신들이 종종 '무한 루프'라는 단어를 사용하는 것을 볼 수 있습니다. 여기서 루프는 고리, 고리로 만들다 라는 의미를 가지고 있죠. 프로그래밍 세계에서 루프는 어떤 일련의 과정의 반복과 순환을 의미합니다. 그래서 무한 루프에 빠졌다라는 말은 반복문에서 벗어나지 못해서 프로그램이 에러가 났다라고 해석할 수 있습니다.

우리의 일상 생활 속에도 반복이라는 개념은 정말 많은 곳에 존재하고 있습니다. 예를 들어볼까요?

✏️To Muko
🗓Muko@tistory.com

안녕하세요, muko님.
티스토리 블로그입니다.

muko님의 블로그에 너무나도 좋은 IT 교육 자료가 많아서 저희가 카카오 메인 페이지에 올려도 되는지 여쭤보려고 이렇게 연락을 남기게 되었습니다.
메인 페이지에 올라가는 것이 괜찮으시다면 회신 부탁드립니다.

감사합니다.
내 마음 속의 티스토리

 

이런 메일을 받았다고 생각해봅시다. 받는 사람 입장에서는, 특히 티스토리에서 IT 블로그를 운영하는 사람이라면 매우 반길만한 메일이죠. 그런데 만약 티스토리 운영 측에서 이러한 내용을 담고 있는 메일을 1000명 한테 보내야 한다면 어떻게 해야할까요? 명단이 저장되어있는 엑셀 파일에서 이름과 이메일 주소를 하나씩 확인해가면서 매번 메일 내용에 닉네임을 바궈가면서 채워줘야하는 엄청나게 번거로운 작업을 해야합니다.

만약 이름, 이메일, 닉네임을 여러개 입력해 놓으면 알아서 메일을 보내주는 프로그램이 있다고 하면 조금은 덜 고생하겠죠? 거기다 엑셀 파일을 읽어와서 알아서 정보를 찾아서 보내주기까지 한다면 더욱 편하게 메일을 보낼 수 있을 겁니다.

프로그래밍에서 반복문이 이런 기능을 가능하게끔 해줍니다.

  1. 파일이 끝날 때 까지 여러 개의 줄을 읽어오기
  2. 해당 줄을 읽을 때 마다 이름과 닉네임, 이메일 주소를 찾아서 내용을 채우고, 메일 보내기

위의 예제를 기반으로 반복문에 대해서 설명을 한다면, 반복문은 인간이 실수하거나 지루해할 수 있는 반복적인 작업을 컴퓨터가 대신 수행하게끔 만든 기능이다.



반복문이 없다면?

반복문이 없다고 가정했을 때, 위의 메일을 3명에게 보내야한다고 가정해봅시다. 각 사람들의 정보는 다음과 같습니다.

{
  name: 'Muko',
  email: 'Muko@tistory.com'
}
{
  name: 'Kim',
  email: 'KoreanKim@naver.com'
}
{
  name: 'Park',
  email: 'JPark@aomg.com'
}

 

그랬을 때 우리가 메일을 보내는 코드를 작성한다고 했을 때 다음과 같이 작성해야 할 겁니다.

// 사람 정보 저장
const Muko = {
  name: 'Muko',
  email: 'Muko@tistory.com'
};

const Kim = {
  name: 'Kim',
  email: 'KoreanKim@naver.com'
};

const Park = {
  name: 'Park',
  email: 'JPark@aomg.com'
};

// 메일 전송 함수 선언
const sendEmail = (person) => {
  const content = `
    ✏️To ${person.name}
    🗓${person.email}

    안녕하세요, ${person}님.
    티스토리 블로그입니다.

    ${person}님의 블로그에 너무나도 좋은 IT 교육 자료가 많아서 저희가 카카오 메인 페이지에 올려도 되는지 여쭤보려고 이렇게 연락을 남기게 되었습니다.
    메인 페이지에 올라가는 것이 괜찮으시다면 회신 부탁드립니다.

    감사합니다.
    내 마음 속의 티스토리
  `;
  console.log(content);
};

// 함수 호출
sendEmail(Muko);
sendEmail(Kim);
sendEmail(Park);


이렇게 보내면 그래도 매번 사람이 복사 붙여넣기 하는 것보다는 조금은 쉽게 보낼 수 있습니다. 그러나 호출부분에 계속해서 사람이 추가될 때마다 코드 한줄이 추가되어야 하고, 만약 사람이 만명이라면 함수 호출 부분에 코드 1만 줄이 추가되어야 하는 문제가 있습니다.

 

이제 반복문을 사용해 봅시다.

편하게 사용하기 위해서 작성하는 것이 프로그래밍 언어인데, 불편하게 만들지 말아야겠죠? 위에 적은 예시를 이번에는 반복문을 통해서 작성해보도록 하겠습니다.

// 사람 정보 저장
const People = [{
    name: 'Muko',
    email: 'Muko@tistory.com'
  }, {
    name: 'Kim',
    email: 'KoreanKim@naver.com'
  }, {
    name: 'Park',
    email: 'JPark@aomg.com'
  }
];

// 메일 전송 함수 선언
const sendEmail = (person) => {
  const content = `
    ✏️To ${person.name}
    🗓${person.email}

    안녕하세요, ${person}님.
    티스토리 블로그입니다.

    ${person}님의 블로그에 너무나도 좋은 IT 교육 자료가 많아서 저희가 카카오 메인 페이지에 올려도 되는지 여쭤보려고 이렇게 연락을 남기게 되었습니다.
    메인 페이지에 올라가는 것이 괜찮으시다면 회신 부탁드립니다.

    감사합니다.
    내 마음 속의 티스토리
  `;
  console.log(content);
};

// 함수 호출
for(let i=0; i<People.length; i++){
  sendEmail(People[i]);
}


이렇게 작성하면 아래 함수 호출 부분이 3줄로 아주 간단하게 해결될 수 있습니다. 마지막 세 줄을 보시면 반복이라는 개념을 구현하기 위해서 for 키워드를 사용한 것을 확인할 수 있습니다. 다른 프로그래밍 언어에 대한 경험이 없으신 분은 이 for문에 대해서 익숙해지는데 조금 시간이 걸릴 수도 있습니다. 차근차근 뜯어보겠습니다.

 

for문

for문은 보통 다음과 같이 사용합니다.

for(초기값, 반복 조건, 업데이트) {
  // 반복 코드
}

먼저 초기값은 말그대로 for문과 관련된 부분에서 사용될 변수를 초기화 하는 파트입니다. 위의 예제에서는 let i=0;이라고 초기화를 했네요. 그 다음으로 반복 조건은 초기값이나 다른 변수를 이용해서 어떤 조건식을 세웠을 때, 그 조건에 truthy한 결과가 나올 때까지 계속해서 반복문을 유지한다는 의미입니다. 따라서 반복 조건을 계속해서 만족한다면 탈출하지 못하는 무한 루프에 빠지는 것이죠. 이런 상황을 방지하기 위한 파트가 바로 업데이트 파트입니다. 위의 코드에서는 i++이라는 업데이트 코드를 작성했는데요, 이 부분은 반복문이 한 번 동작하고 나서 작동하는 코드입니다. 그래서 위의 예제에서 처음에 i=0에서 시작했다가, 반복문이 한 번 돌고나서 i가 1이 증가하게 됩니다. 계속해서 반복문이 돌다가 i의 크기가 People.length와 값이 같아진 순간 for문에서 벗어나게 되는거죠. People의 길이가 3이므로 반복문은 총 3번 동작하게 됩니다.

더 쉬운 예제를 살펴볼까요? 이번에는 'Hello, Javascript!'라는 문장을 10번 출력하는 코드를 작성해보도록 하겠습니다.

for(let i=0; i<10; i++){
  console.log('Hello, Javascript!');
}

이렇게 반복문을 사용할 수 있는데, 이 for문을 연습하기 가장 좋은 방법은 문제를 풀어보는 것입니다. 내가 작성한 코드가 실제로 올바르게 동작하는지 확인하는 것이 매우 중요한데요, 내가 혼자서 확인하기 보다는 입력과 출력이 정해져있고, 채점까지 해주는 환경에서 코드를 작성하면 재미가 배가 됩니다. 백준 단계별로 풀어보기 for문 편 포스팅을 확인해보세요! 백준이라는 사이트에서 for문에 관한 아주 기초 문제들을 모아놓은게 있는데, 그 풀이 포스팅을 올려놓았습니다.

 

while문

자바스크립트에서는 for문 뿐만 아니라 while이라는 키워드를 이용한 반복문도 있습니다. while문은 다음과 같이 사용합니다.

let i=0;
while(i < 10) {
  console.log('Hello, Javascript!');
}

while문의 특징은 초기값과 업데이트 부분없이 반복 조건만을 사용한다는 점입니다. 따라서 탈출 조건이 생길 수 있도록 변수와 업데이트 부분을 while문 안팎에서 잘 작성해야 합니다. 생김새는 다르지만, 동작하는 모습자체는 크게 다르지 않은 것을 확인할 수 있습니다.

 

forEach, map (심화)

보통 다른 프로그래밍 언어에서는 이렇게 두 가지를 이용해서 반복문을 동작시킵니다만, 자바스크립트에서는 또 다른 방법이 존재합니다. 자바스크립트 배열의 메서드를 이용하는 방법인데요, 여기에는 forEach와 map이 있습니다. 여러 복잡한 반복 조건 없이, 단순하게 배열을 탐색하기 위한 반복문일 때 매우 효율적으로 작성가능한 문법인 만큼 정말 많이 사용되며, 잘 활용한다면 짧은 코드를 작성해서 직관적인 구현이 가능합니다.

기본적으로 forEach와 map은 1개의 인자를 받게끔 되어있는데, 이 인자는 함수여야 합니다. 또한 이 함수는 3개의 인자를 가질 수 있으며 1개만 받아도 동작합니다. 이 3개의 인자는 각각 배열의 요소, 해당 요소의 index, 그리고 배열 그 자체를 의미합니다. 예시 코드를 보시면 이해가 더 쉽습니다.

const members = ['kim', 'park', 'Muko'];

members.forEach(person => {
  console.log(person);
};

members.forEach((person, index) => {
  console.log('name: ', person, ', index: ', index);
}

members.forEach((person, index, array) => {
  console.log('name: ', person, ', inArray name: ', array[index]);
}

const result = members.map(person => {
  return 'My name is ' + person;
};

const result2 = members.map((person, index, array) => {
  return 'name: ' + person + ', inArray name: ' + array[index];
}

코드를 보시면 forEach와 map 둘 다 배열을 탐색하면서 인자로 전달한 요소의 값을 이용해서 동작시키는 코드를 구현한다는 공통점을 가짐을 파악할 수 있습니다. 하지만 약간 다른 점이 존재하는데요, 바로 return의 유무 입니다. forEach의 return은 undefined인 반면에 map은 인자로 받은 함수의 결과값들로 만든 새로운 배열을 return 합니다. 여기서 인자로 받은 함수라는 것을 보통 콜백 함수라고 말하는데, 추후에 자세하게 다루도록 하겠습니다.

정리하자면, 어떤 배열이 있을 때 배열을 탐색(순회)하면서 요소들을 각각 가공해서 새로운 배열(원래 배열과 길이가 동일한)을 반환받고자 할 때는 map을 사용하면 됩니다. 반면에 배열의 요소들을 활용해서 총 합을 구한다던지, 배열의 길이와 상관없는 어떤 결과를 도출해내고자 할 때는 forEach를 사용하면 됩니다.

추가적으로, for과 while문과 달리 forEach와 map 메서드를 사용하면 배열의 모든 요소를 탐색할 때 까지 종료되지 않습니다. 만약 중간에 반복문을 탈출하고 싶을 경우에는 반복 코드에서 조건문과 break 등을 이용해서 탈출하는 코드를 추가적으로 작성해야합니다.



여기까지 따라오시느라 수고하셨습니다.
다음 시간에는 DOM에 대해서 다루도록 하겠습니다! 👍

댓글6