자바스크립트
함수형 프로그래밍
map()

자바스크립트 map(): index 매개변수, return break continue, async callback

이 포스트에서는 자바스크립트의 map() 메서드에 대해 자세히 알아보겠습니다. 구체적으로, index 매개변수와 return, break, continue 키워드, 비동기 콜백 함수 async callback 사용 예제를 알아볼게요.

1. map() 메서드 기초 이해하기

map() 메서드는 주어진 배열의 각 요소에 대해 함수를 적용한 결과를 가진 새로운 배열을 생성합니다. 이를 통해 배열의 값을 쉽게 변환하거나 계산할 수 있습니다. 이 과정에서 기존 배열을 수정하거나 조작하지 않습니다. 함수형 프로그래밍의 기본인 immutable, 즉 불변성을 가진 자료형을 기반으로 동작하기 때문입니다.

map() 메서드는 배열에 대한 메서드로 호출하며, 인자 (argument) 로 콜백 함수를 전달합니다. 콜백 함수는 배열의 각 요소에 대해 실행되며, 반환된 결과가 새로운 배열에 포함됩니다.

코드로 설명해보자면, [1, 2, 3].map(callback) 문을 실행하는 것은 [callback(1), callback(2), callback(3)] 문과 같습니다.

기본적인 사용법을 알아보겠습니다.

const newArray = array.map(callbackFunction);

2. forEach(), filter(), reduce() 메서드와 비교

map 메서드는 filter(), forEach(), reduce() 메서드와 같은 다른 배열 메서드와 함께 사용되기도 합니다. 각 메서드는 특정한 목적에 따라 배열을 처리하는 방법이 다릅니다.

  • forEach(): 배열의 모든 요소를 순회하며 지정한 콜백 함수를 실행합니다.
  • reduce(): 이전 값과 현재 값을 결합하는 함수를 적용하여 배열의 값을 하나의 값으로 합산합니다.
  • filter(): 지정된 조건을 통과하는 요소만 남겨서 새 배열을 만듭니다.

더 자세한 내용은 각각의 포스트를 참고해주세요.

3. map() 메서드와 return, break, continue 키워드

함수형 프로그래밍 기반의 map() 메서드는 배열의 모든 원소를 순회하고 같은 길이의 새 배열을 리턴하도록 동작합니다. 이 때문에, 순회를 정지하거나, 재개하는 break, continue 키워드 사용을 지원하지 않습니다.

다만, 특정 원소에 아무 조작을 하지 않길 원한다면, return키워드로 현재 원소값을 리턴해줄 수 있습니다. continue 키워드와 비슷한 역할을 하는 것이죠.

아래 예제에서 요소값이 3이 아닌 경우에, return 키워드로 element 자체를 리턴해서 원래 원소값을 유지하도록 했습니다.

const array = [1, 2, 3, 4, 5];
 
const mappedArray = array.map((element) => {
  if (element === 3) {
    return element * 10; // Return transformed value
  }
  return element; // Return original value
});
 
console.log(mappedArray);
 
// Output: [1, 2, 30, 4, 5]

4. 콜백 함수 내에서 index, array 매개변수 활용하기

map() 메서드의 콜백 함수는 현재 값뿐만 아니라 각 인덱스와 배열 자체에 접근하는 레퍼런스를 제공합니다. 이를 통해, 더욱 유연한 콜백 함수를 정의할 수 있습니다.

const numbers = [10, 20, 30, 40, 50];
 
numbers.map((number, index, array) => {
    return `Index: ${index}, Number: ${number}, Array: ${array}`
});
 
// Output:
// [
//   'Index: 0, Number: 1, Array: 1,2,3,4,5',
//   'Index: 1, Number: 2, Array: 1,2,3,4,5',
//   'Index: 2, Number: 3, Array: 1,2,3,4,5',
//   'Index: 3, Number: 4, Array: 1,2,3,4,5',
//   'Index: 4, Number: 5, Array: 1,2,3,4,5'
// ]

5. map() 메서드 실제 활용 예제

5.1. 숫자 배열 변환하기

다음 예제에서는 map 메서드를 사용하여 주어진 숫자 배열의 각 요소를 제곱한 결과를 가진 새 배열을 생성합니다.

const numbers = [1, 2, 3, 4, 5];
const squaredNumbers = numbers.map(num => num * num);
 
console.log(squaredNumbers); // [1, 4, 9, 16, 25]

5.2. 문자열 배열 형식 지정하기

이 예제에서는 문자열 배열의 각 요소를 대문자로 변환하여 새로운 배열을 생성합니다.

const words = ['hello', 'world', 'javascript'];
const uppercaseWords = words.map(word => word.toUpperCase());
 
console.log(uppercaseWords); // ['HELLO', 'WORLD', 'JAVASCRIPT']

5.3. 객체 배열 매핑하기

이 예제에서는 객체 배열의 각 요소에서 특정 속성을 추출하여 새로운 배열을 생성합니다.

const users = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }];
const userNames = users.map(user => user.name);
 
console.log(userNames); // ['Alice', 'Bob', 'Charlie']

5.4. 다차원 배열에서 map() 메서드 사용하기

이 예제에서는 다차원 배열에서 Map 메서드를 중첩하여 사용합니다. 2번째 줄에서 중첩되는 map 메서드를 잘 봐주세요.

const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
const squaredMatrix = matrix.map(row => row.map(num => num * num));
 
console.log(squaredMatrix); // [[1, 4, 9], [16, 25, 36], [49, 64, 81]]

6. Async callback: 비동기 콜백 함수

map() 메서드에 전달하는 콜백 함수는 비동기로 정의할 수도 있습니다. 비동기 함수는 주로, API 호출, 파일 등 I/O 작업, Promise 객체 작업 등에서 메인 스레드 동작을 멈추지 않도록 사용합니다.

콜백 함수로 비동기 함수를 전달하면, map() 메서드의 리턴값은 Promise 객체가 됩니다. 따라서, 아래와 같이 async await 키워드와 함께 사용해야 합니다.

fetchUserData()는 임의로 선언한 API 호출 함수이며 비동기로 정의되었습니다. 이 함수를 매핑 함수로 사용하는 map 메서드는 다수의 Promise를 관리하는 all 메서드를 통해, API로부터 받은 데이터를 출력할 수 있습니다.

const fetchUserData = async (id) => {
  // Simulated async operation, fetching user data
  const response = await fetch(`https://api.example.com/users/${id}`);
  return await response.json();
};
 
const userIds = [1, 2, 3];
 
const getUserData = async () => {
  const userData = await Promise.all(userIds.map((id) => fetchUserData(id)));
  console.log(userData);
};
 
getUserData();

7. map() 사용 시 오류 처리 및 주의해야 할 점

7.1. 콜백 함수에서 값을 반환하지 않는 경우 방지하기

map 메서드의 콜백 함수에서 반환되는 값이 새 배열의 요소가 됩니다. 만약 콜백 함수에서 값을 반환하지 않으면, 새로운 배열의 해당 요소는 undefined로 설정됩니다. 따라서 코드 작성 시 반환 값이 있는지 확인하는 것이 중요합니다.

const numbers = [1, 2, 3, 4, 5];
const wrongResult = numbers.map(num => { num * num });
 
console.log(wrongResult); // [undefined, undefined, undefined, undefined, undefined]

7.2. 배열 내의 빈 요소 처리

배열 내에 빈 요소가 있는 경우, map 메서드는 해당 요소에 대해 콜백 함수를 실행하지 않습니다. 빈 요소의 인덱스는 새로 생성된 배열에서도 유지되며 값은 undefined로 설정됩니다. 이러한 특성을 이해하고 필요한 경우 빈 요소 처리를 명시적으로 구현해야 합니다.

const sparseArray = [1, , , 4, 5];
const result = sparseArray.map(num => num * 2);
 
console.log(result); // [2, undefined, undefined, 8, 10]

7.3. map 메서드의 콜백 함수 내부에서 배열을 수정하지 않기

map() 메서드의 콜백 함수 내에서 원본 배열을 수정하는 것은 좋지 않은 방법입니다. 이렇게 하면 예기치 않은 동작이 발생할 수 있으며, 코드의 가독성과 유지 보수에도 영향을 줍니다. 대신, 필요한 경우 새로운 배열을 만들어 원본 배열과 새 배열을 독립적으로 유지하는 것이 좋습니다.

6. 마치며

자바스크립트 map() 메서드는 웹 개발 시 배열 변환이 필요한 모든 곳에서 가장 먼저 생각할 수 있는 도구입니다. 그만큼 일상적으로 사용할 수 있는 메서드입니다. 이번 프소팅으로 map() 메서드에 대한 감을 잡았다면 MDN 공식 문서 (opens in a new tab)를 이용해 더 깊이 있게 익혀보세요.

copyright for Javascript map

© 2023 All rights reserved.