JavaScript의 map 메소드는 ECMAScript 5에 도입되어 배열 조작과 변환을 위한 필수 도구로 자리 잡았습니다. 이 메소드는 다양하고 간단하며, 현대 JavaScript 프로그래밍에서 필수적인 요소가 되었습니다.

이 글에서는 map 메소드의 문법과 기본 데이터 조작부터 고급 함수형 프로그래밍 패러다임에 이르기까지 다양한 적용 방법을 탐색해보겠습니다.

목차

map 메소드 기본

JavaScript에서 Map 메소드는 배열의 각 요소에 대해 반복하면서 지정된 함수를 각 요소에 적용할 수 있게 하는 고차 함수입니다. 이 함수는 일반적으로 콜백 함수라고 불립니다.

Map 메소드의 핵심 기능은 원본 배열 자체를 수정하지 않으면서 이 콜백 함수를 각 요소에 적용한 결과를 바탕으로 새 배열을 생성한다는 것입니다.

map 메소드의 문법

Map 메소드의 문법은 간단합니다:

const newArray = array.map(callback(currentValue[, index[, array]]) {
  // newArray의 요소를 반환하기 위해 무언가를 실행
}[, thisArg]);
  • array: 반복하고자 하는 원본 배열입니다.
  • callback: 배열의 각 요소에 실행될 함수입니다.
  • currentValue: 배열에서 현재 처리되고 있는 요소입니다.
  • index (선택사항): 현재 처리되고 있는 요소의 인덱스입니다.
  • array (선택사항): map이 호출된 배열입니다.
  • thisArg (선택사항): 콜백 함수 내에서 this가 참조할 수 있는 선택적 객체입니다.

map의 일반적인 사용 사례

데이터 변환

시나리오: 숫자 배열이 있고 배열에서 각 숫자를 두 배로 하고 싶습니다.

Map 없이:

const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = [];
for (let i = 0; i < numbers.length; i++) {
  doubledNumbers.push(numbers[i] * 2);
}
// doubledNumbers: [2, 4, 6, 8, 10]

기존 방식에서는 doubledNumbers라는 빈 배열을 초기화하고, numbers 배열의 각 요소를 순회하면서 for 루프를 사용하여 각 요소를 2배로 만든 후, doubledNumbers 배열에 두 배된 값을 넣습니다.

Map 사용:

const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map(num => num * 2);
// doubledNumbers: [2, 4, 6, 8, 10]

map 메소드를 사용하여, 숫자 배열(numbers)의 각 요소(num)를 두 배로 하는 콜백 함수를 전달합니다.

map 메소드는 배열의 각 요소를 순회하면서 제공된 콜백 함수를 적용하고, 두 배된 값을 포함하는 새 배열(doubledNumbers)을 반환합니다. 이 접근 방식은 코드를 단순화하고 가독성을 향상시킵니다.

객체 변환

시나리오: 사용자 객체의 배열이 있고, 새 배열에 그들의 ID만 추출하고 싶습니다.

Map 없이:

const users = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 3, name: 'Doe' }
];
const userIds = [];
for (let i = 0; i < users.length; i++) {
  userIds.push(users[i].id);
}
// userIds: [1, 2, 3]

전통적인 방법에서는 userIds라는 빈 배열을 초기화하고, users 배열의 각 사용자 객체를 순회하면서 for 루프를 사용하여 각 사용자 객체에서 id 속성을 추출한 다음, 추출된 id 값을 userIds 배열에 넣습니다.

Map 사용:

const users = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 3, name: 'Doe' }
];
const userIds = users.map(user => user.id);
// userIds: [1, 2, 3]

map 메소드를 사용하여, users 배열의 각 사용자 객체(user)에서 id 속성을 추출하는 콜백 함수를 제공합니다.

map 메소드는 배열의 각 요소를 순회하면서 콜백 함수를 적용하고, id 값만을 포함하는 새 배열(userIds)을 반환합니다. 이 접근 방식은 코드를 단순화하고 유지보수성을 향상시킵니다.

문자열 조작

시나리오: 이름으로 이루어진 배열이 있고, 모든 이름을 대문자로 변환하고 싶습니다.

Map 없이:

const names = ['John', 'Jane', 'Doe'];
const uppercasedNames = [];
for (let i = 0; i < names.length; i++) {
  uppercasedNames.push(names[i].toUpperCase());
}
// uppercasedNames: ['JOHN', 'JANE', 'DOE']

기존 방식에서는, uppercasedNames라는 빈 배열을 초기화하고, for 루프를 사용하여 names 배열의 각 요소를 순회하며, toUpperCase() 메소드를 사용해 각 이름을 대문자로 수동 변환합니다. 마지막으로 대문자로 변환된 이름을 uppercasedNames 배열에 추가합니다.

Map 사용:

const names = ['John', 'Jane', 'Doe'];
const uppercasedNames = names.map(name => name.toUpperCase());
// uppercasedNames: ['JOHN', 'JANE', 'DOE']

map 메소드를 사용하면, toUpperCase() 메소드를 사용하여 각 이름(name)을 대문자로 변환하는 콜백 함수를 전달합니다.

map 메소드는 배열의 각 요소를 순회하며 콜백 함수를 적용하고, 대문자 이름을 포함하는 새 배열(uppercasedNames)을 반환합니다. 이 접근 방식은 코드를 단순화하고 가독성을 향상시킵니다.

작업과 인덱스

시나리오: 숫자로 이루어진 배열이 있고, 각 숫자를 해당 인덱스만큼 증가시키고 싶습니다.

Map 없이:

const numbers = [1, 2, 3, 4, 5];
const incrementedNumbers = [];
for (let i = 0; i < numbers.length; i++) {
  incrementedNumbers.push(numbers[i] + i);
}
// incrementedNumbers: [1, 3, 5, 7, 9]

기존 방식에서는, incrementedNumbers라는 빈 배열을 초기화하고, for 루프를 사용하여 numbers 배열의 각 요소를 순회하며, 숫자에 인덱스 i를 더하고, 증가된 값을 incrementedNumbers 배열에 추가합니다.

Map 사용:

const numbers = [1, 2, 3, 4, 5];
const incrementedNumbers = numbers.map((num, index) => num + index);
// incrementedNumbers: [1, 3, 5, 7, 9]

map 메소드를 활용하여, 현재 값(num)과 인덱스(index)를 매개변수로 받는 콜백 함수를 전달합니다. 콜백 함수 내에서 각 숫자에 인덱스를 더합니다.

map 메소드는 배열의 각 요소를 순회하며 콜백 함수를 적용하고, 증가된 값을 포함하는 새 배열(incrementedNumbers)을 반환합니다. 이 접근 방식은 각 숫자를 해당 인덱스만큼 증가시키는 로직을 우아하게 처리합니다.

결론

데이터 조작, 객체 변형, 또는 문자열 조작이든, Map 메소드는 다양한 프로그래밍 작업에 대한 강력한 해결책을 제공함으로써 모든 JavaScript 개발자의 도구 상자에 없어서는 안 될 중요한 부분이 됩니다.

전통적인 접근 방식과 Map 메소드를 비교하고 다양한 사용 사례를 탐색함으로써, 그것의 능력에 대한 더 깊은 이해를 얻을 수 있습니다.