프로그래머스 문제 풀면서 메서드를 찾을 때마다 10에 8번은 본 reduce 메서드.
사용을 해보고 싶었지만 너무 어렵고 동작 원리를 이해 못해서 다른 방벙으로 문제 풀이를 해 왔는데 오늘 드디어 reduce 와의 전쟁을 선포하다. 💣
🔎 Array.prototype.reduce()
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
우선 reduce는 배열에 사용하는 메서드이다.
mdn 문서의 말을 빌려오자면, reduce는 배열의 각 요소에 대해 주어진 리듀서 (reducer) 함수를 실행하고, 하나의 결과값을 반환합니다. 라고 한다.
reduce는 네 개의 인자를 가지는데 이는 아래와 같다.
참고로 원하는 값을 뽑기 위해서는 각 인자의 위치를 정확히 해 주어야 한다!
1️⃣ 누산기 (acc) - 필수 ⭐️
2️⃣ 현재 값 (cur) - 필수 ⭐️
3️⃣ 처리할 현재 요소의 index (idx) - 선택
4️⃣ reduce를 호출한 배열 (src) - 선택
그리고 중요한 initialValue도 있다. 한글로 해석하면 '기초값'이라고들 말한다. 중요하지만 기초값은 선택 사항이다.
그런데 왜 중요하다고 말했냐면...! 그 이유는 아래서 계속 설명 할 예정!
4개의 인자를 사용해서 간단하게 동작 방법에 대해 알아보자.
var a = [1, 2, 3, 4, 5];
a.reduce((acc, cur, idx, arr) => {
console.log(`acc : ${acc} | idx : ${idx}`);
// 초기값 0으로 지정했을 때
// acc : 0 | idx : 0
// acc : 1 | idx : 1
// acc : 3 | idx : 2
// acc : 6 | idx : 3
// acc : 10 | idx : 4
return acc + cur;
}, 0);
a라는 배열을 만들어서 숫자로 이루어진 1~5를 넣었다.
이제 reduce를 사용해서 어떤식으로 동작하는지 확인해 보자.
코드를 보면 기초값을 0으로 설정했는데 0으로 설정을 굳이 한 이유가 바로 여기에 나타나 있다.
만약 0을 적지 않으면 초기값이 default값인 1로 들어가는데 이는 idx가 0부터가 아닌 1부터 시작을 해서 0을 건너 뛰게 됨으로 내가 원하는 결과값과 차이점이 발생할 수 밖에 없다.
한번 1이 아닌 0 (초기값 선정 x)으로 확인해 볼까?
var a = [1, 2, 3, 4, 5];
a.reduce((acc, cur, idx, arr) => {
console.log(`acc : ${acc} | idx : ${idx}`);
// acc : 1 | idx : 1
// acc : 3 | idx : 2
// acc : 6 | idx : 3
// acc : 10 | idx : 4
return acc + cur;
});
idx가 0이 아닌 1부터 시작됨을 알 수 있다. 따라서 특별한 상황이 아니라면 초기값을 0으로 두는게 좋겠다.
이는 프로그래머스 문제에서도 적용되었는데 배열 a와 배열 b의 요소들을 각각 차례대로 곱해서 더하는 문제였다.
a.reduce((acc, val, idx) => acc + val * b[idx], 0);
이렇게 해당 인자를 이용해서 간단하게 더하고 곱하는 식을 만들 수 있다!
여기서도 0을 빼면 값이 완전히 틀려지기 때문에 초기값을 0으로 셋팅해 주었다.
이처럼 reduce를 사용하면 연산외로 찾고자 하는 값을 찾아낼 수 있다.
사실 아직은 사용하기 어색하고 익숙하지 않지만 꾸준히 연습해서 나중엔 잘 사용해 보고 싶은 욕심이 있다!
var arr = [1, 2, 3, 4];
return arr.reduce((acc, cur) => acc + cur); // 10
간단하게 배열의 모든 값을 합산시키는 방법을 reduce를 사용해 찾아보자.
누산기 현재 값으로 배열 내 모든 값을 합산 해 줄 수 있다!
참고로 위 코드는
var arr = [1, 2, 3, 4];
var sum = 0;
for(var i = 0; i < arr.length; i++){
sum += arr[i];
}
return sum; // 10
이 코드랑 동일하다!
reduce로 여러줄의 코드를 1줄로 간편하게 줄일 수 있다.
arr.reduce((acc, cur) => acc + cur); // acc = acc += cur
acc는 누적 값이고 cur는 배열 요소를 돌면서 acc와 더해 주기 때문에
배열 요소의 모든 값을 합산 해 준다.
참고로 문자열로 이루어진 배열도 가능하다. ㄷㄷㄷ
var arr = ["a", "b", "c", "d"];
console.log(arr.reduce((acc, cur) => acc + cur)); // abcd
그리고 신기한 점 하나 발견했는데, return 한 값은 배열 상태가 아니라는 것! 따라서 결과 값을 배열상태가 아닌 상태로 뽑고 싶을때 사용하면 딱 일 것 같다.