정수 배열 numbers가 매개변수로 주어집니다. numbers의 각 원소에 두배한 원소를 가진 배열을 return하도록 solution 함수를 완성해주세요.
// 배열에 각 두배로 곱하라는 얘기다.
numbers | result |
---|---|
[1, 2, 3, 4, 5] | [2, 4, 6, 8, 10] |
[1, 2, 100, -99, 1, 2, 3] | [2, 4, 200, -198, 2, 4, 6] |
// map을 활용한 나의 풀이법
function solution(numbers) {
return numbers.map(item => Number(item)*2)
}
우선 나는 map으로 배열을 반환하는 걸 택했다. 일단 현업에서 가장 많이 쓰고 직관적으로 배열을 돌 수 있다.
이는 map으로 작업하면 배열에 있는 각 수를 순회를 돌면서 해당 연산을 실행한다. 비교적 간단한 문제다.
그런데 풀이 방법을 살펴보니 다른 방법으로 작업한 방법도 많이 채택한다.
이는 reduce 였다.
// reduce 풀이법
function solution(numbers) {
return numbers.reduce((acc, item) => {
acc.push(Number(item) * 2);
return acc;
}, []);
}
map과 차이점이라고 한다면 단순히 변환된 배열을 보여주는게 map이라면, 초기값을 []을 잡고 동작하는게 reduce다.
reduce 동작원리를 예를 들어서 보여주면
reduce
의 초기값 acc = []
첫 번째 요소 1
을 가져와 1
* 2 = 2
→ acc = [2]
두 번째 요소 2
를 가져와 2
* 2 = 4
→ acc = [2, 4]
세 번째 요소 3
을 가져와 3
* 2 = 6
→ acc = [2, 4, 6]
네 번째 요소 4
를 가져와 4
* 2 = 8
→ acc = [2, 4, 6, 8]
최종적으로 [2, 4, 6, 8]
을 반환
요소에 누적연산을 도는 원리다.
여기서 궁금증이 들었던 부분이 생겼다. map과 reduce가 같은 결과를 가져온다면, 성능상으로 어떤게 더 우위일까?
map은 배열을 직접 변환하는 데 최적화된다.
map은 내부적으로 배열 크기를 미리 알고 있어서, 새로운 배열을 최적화된 크기로 생성한다.
즉, map은 반환할 배열의 메모리를 미리 할당하기 때문에 더 빠르다.
reduce는 누적값을 갱신하면서 추가적인 연산 수행
reduce는 첫 번째 인자로 누적 변수(acc) 를 관리하면서 새로운 배열을 수동으로 생성해야 한다.
배열의 크기를 모르기 때문에, 매번 .push()를 호출하면서 배열 크기를 동적으로 늘려야 한다.
이로 인해 불필요한 메모리 할당 및 조정이 발생할 수 있다.
map이 직관적으로 더 빠른 결과를 불러온다.
하지만 reduce를 사용하게 된다면, 배열을 다른 구조로 바꿀때 더 유리할 수 있다.
sum
, groupBy
, flatten
등