본문 바로가기
자바스크립트(JavaScript)/프로그래머스 문제풀기

[programmers - js] 배열 두 배 만들기 / reduce, map

by yerica 2024. 12. 16.

문제 내용

나의 대답

answer라는 배열을 만든 뒤 반복문을 통해 배열 삽입

function solution(numbers) {
    const answer = [];
    for(let i = 0; i < numbers.length; i++){
        answer.push(numbers[i] * 2)
    }
    return answer;
}

 

다른 사람의 풀이

reduce 사용
function solution(numbers) {
    return numbers.reduce((a, b) => [...a, b * 2], []);
}
reduce 는 배열의 각 요소를 순회하며 값을 누적하여 단일 값(또는 객체, 배열 등)을 반환한다.
reduce는 map이나 filter같은 단일작업을 넘어서누적 계산, 변환, 필터링, 배열 합치기와 같은 복잡한 작업을 처리할 수 있기 때문에 활용도가 높다.

array.reduce((accumulator, currentValue) => { ... }, initialValue);​


* accumulator : 누적된 결과 저장
* currentValue :  현재 순회중인 요소
* initialValue : 초기값

위의 문제풀이 에서는 먼저 initialValue를 빈 배열 [ ] 로 설정했다. 
즉, a 의 초기 상태는 빈 배열인 것이다. ( a = [ ] )
이후 배열의 각 요소를 순회하며, 콜백 함수 (a,b) => [ ... a, b * 2] 가 실행된다.
문제풀이 에서의 콜백함수는 스프레드 연산자(...)를 사용해 누적된 배열 a에 b * 2 를 추가한다.


numbers = [ 1, 2 ] 라고 가정했을 경우 순서는 다음과 같다.
numbers[0] : b = 1 → a = [ ] b * 2 = 2 a = [...[ ], 2] = [2]
numbers[1] : b = 2 a = [2] b * 2 = 4 a = [...[2], 4] = [2, 4]

map 사용
const solution = (numbers) => numbers.map((number) => number * 2)
map 은 배열의 각 요소를 순회하며, 지정된 콜백 함수를 적용한 결과를 새로운 배열로 반환한다.
그렇기 때문에 배열의 각 요소를 변환하거나 새로운 배열을 생성할 때 사용된다.
결과 배열의 길이원본 배열과 동일하기 때문에, 직관적이고 간단하다.
요소를 변경하거나 필터링하지 않고 단순히 변환하는 경우에 사용하기 적합하다.

위의 문제풀이에서 map 안의 number는 배열의 각 요소를 나타내며, 각 요소를 * 2 하는 작업을 진행한다.

numbers = [ 1, 2 ] 라고 가정했을 경우 순서는 다음과 같다.
numbers[0] : number = 1 → number * 2 = 2 → numbers[0] = 2
numbers[1] : number = 2 → number * 2 = 4 → numbers[1] = 4
map / reduce 비교
특징 map reduce
주요 목적 배열 요소의 변환 배열을 축소하여 단일 값(또는 다른 형태) 반환
반환 결과 항상 배열 단일 값, 배열, 객체 등 원하는 형태
작업 대상 요소별 변환 작업 누적 계산, 필터링, 변환 등 다양한 작업 가능
가독성 간결하고 직관적 복잡한 작업에서는 가독성이 떨어질 수 있음
유연성 제한적(요소별 변환만 가능) 매우 유연함(다양한 형태의 작업 가능)
사례 배열의 요소를 단순 변환할 때 합계, 곱, 필터링, 객체 생성 등 복잡한 작업

다음과 같이 복잡한 예시에선 reduce가 더 적합하다.

// 객체 생성
const fruits = ['apple', 'banana', 'apple', 'orange'];
const fruitCount = fruits.reduce((acc, fruit) => {
    acc[fruit] = (acc[fruit] || 0) + 1;
    return acc;
}, {});
console.log(fruitCount); // { apple: 2, banana: 1, orange: 1 }​


acc의 초기값을 빈 객체 { } 로 설정한 다음 fruits의 배열을 처음 부터 끝까지 순회한다.
acc는 객체, fruit는 key, acc[ fruit ] = (acc[ fruit ] || 0) +1 의 결과는 fruit의 value로 저장된다.
acc[ fruit ]에서 ( acc[ fruit ] || 0)으로 해당 과일이 acc 객체에 없으면 0으로 초기화 한 뒤 + 1 시키는데,
fruits의 첫번째 인덱스를 진행시켜보면 acc[ 'apple' ] 이 되는데, 현재 acc는 빈 배열이고 따라서 acc[ 'apple' ]은 undefined이다.
결과적으로 ( undefined || 0) 는 0 이기 때문에,  0 + 1 acc[ 'apple' ] = 1 이 된다.
즉, acc = { apple : 1 }이 되는 것이다.