자바스크립트의 배열은 수많은 내장 메소드가 있는데, 그 중 강력한 메소드 중에 하나로 데이터 핸들링 시 자주 쓰인다는 reduce 메소드.
하지만 array.reduce()는 mdn을 읽어봐도 당최 무슨 말인지 모르겠고, 강력한 거 다 좋은데 그래서 언제 어떻게 왜 쓰는건데! 라는 답답함을 안고 지내다가 며칠 전 유투브 ZeroCho TV 채널의 자바스크립트 강좌를 보다가 광명을 찾았다.
구문: array.reduce((누적값, 현재값) => (다음 누적값 표현식), 초기값)
구문을 봐도 무슨 말인지 모르겠는 게 당연하다. 바로 예제를 보자.
[1, 2, 3, 4].reduce((a, c) => (a + c), 0)
// a (accumulator) : 누산기
// c (currentValue) : 현재 요소
// 초기값 = 0 (optional)
(a, c) => a + c 가 콜백 함수가 들어가는 자리이다. 이 때 a, c 는 parameter로 매개변수명은 마음대로 지어도 상관없지만, 매개변수의 자리(위치)가 중요하다.
초기값은 optional로 없어도 되고, 초기값을 세팅해 주면 초기값이 처음 누적 값이다.
여기까지도 무슨 말인지 잘 모를 수 있다. 누적값과 변수의 요소를 표로 그려보자.
누적 a 값 (a + c) | c : 배열 [1, 2, 3, 4]의 요소가 인덱스 순서대로 들어간다 |
0 (초기값 0이 처음 누적값이기 때문) | 1 |
1 (윗줄 0 + 1 의 값) | 2 |
3 (윗줄 1 + 2 의 값) | 3 |
6 (윗줄 3 + 3의 값) | 4 |
10 (윗줄 6 + 4의 값으로 최종 리턴 값) |
비슷한 예제를 하나 더 살펴보자.
[1, 2, 3, 4].reduce((a, c) => (a * c), 1) // expected output: 24
첫 번째 예제와 차이점은 a와 c를 더하는 게 아니라 곱해주는 것이 누적값이고, 곱셈을 해야 하니 초기값을 0이 아니라 1로 세팅해 주었다.
a (a * c) | c : 배열 [1, 2, 3, 4]의 요소 인덱스 순서대로 |
1 (초기값 1) | 1 |
1 (1 * 1) | 2 |
2 (1 * 2) | 3 |
6 (2 * 3) | 4 |
24 (6 * 4) |
참 간단하죠?
위에 초기값은 optional 하다고 했는데, 초기값이 세팅되지 않으면 배열의 첫 번째 요소가 초기값이 된다. 이 때 배열의 인덱스 상 0번째 요소가 초기값으로 들어가서 c는 인덱스상 1번째 요소부터 들어간다. 따라서 위의 덧셈 예제로 돌아가보면 a = 1 ([1, 2, 3, 4][0]의 값), c = 2 ([1, 2, 3, 4][1])인 두 번째 줄부터 계산되며 결과값은 동일하다. 곱셈의 경우도 마찬가지로 계산한 표의 첫 번째 줄이 지워지고 두 번째 줄부터 계산되며 결과값은 24로 동일하다.
이렇게만 보면 reduce 메소드를 단순 덧셈/곱셈 누적 결과값을 반환해주는 메소드라고 알기 쉬운데 그렇지 않다.
아래는 reduce 메소드를 사용해 배열을 객체로 바꿔주는 예제이다.
['철수', '영희', '민지', '지원'].reduce((a, c, i) => { a[i] = c; return a }, {})
reduce 메소드의 콜백함수에서 위의 예제와 다르게 세 번째 parameter가 들어갔다. 여기서 i는 index다.
이번에는 초기값이 빈 객체로 세팅되어 있다. 위와 똑같이 표를 그려보자.
a : a[i] = c | c : 배열 ['철수', '영희', '민지', '지원']의 요소 | i : index |
{} (초기값 빈 객체) | '철수' | 0 |
{ 0: '철수'} | '영희' | 1 |
{0: '철수', 1: '영희'} | '민지' | 2 |
{0: '철수', 1: '영희', 2: '민지'} | '지원' | 3 |
{0: '철수', 1: '영희', 2: '민지', 3: '지원'} |
reduce가 단순 누적값 계산을 하는데 쓰이는 메소드가 아니라는 걸 알 수 있다. 이 외에도 다양한 활용법이 있을 것 같은데 아직은 reduce 메소드의 작동 원리를 파악한 기쁨만으로도 충분하니 차차 알아가보도록 하자. 😎
참고자료: ZeroCho TV - 자바스크립트 강좌 8-4. 평균 반응속도 구하기
'배워서 남 주자' 카테고리의 다른 글
li 요소는 왜 ul 요소의 자식 요소여야만 할까? (0) | 2022.11.16 |
---|---|
children vs. childNodes (0) | 2022.11.10 |
변수, 선언, 할당, 메모리 그게 다 뭔데? (부제: 원시자료형과 참조자료형의 차이) (1) | 2022.11.07 |
배열과 객체 순회 (0) | 2022.11.06 |
함수 선언식과 함수 표현식의 차이 (0) | 2022.11.01 |