Javascript/자바스크립트 문법

[Javascript] ES6 문법 7.2 - 배열 함수 2 ( reduce() 함수)

isfp_yykkng 2023. 4. 21. 21:08

ES6 문법 7.2 - 배열 함수 2 ( reduce() 함수)

reduce() 함수

reduce() 함수는 배열의 각 요소에 대해 사용자가 정의한 리듀서(reducer) 콜백 함수를 실행하고 하나의 결과값을 순서대로 반환한다.

 리듀서 함수의 반환값은 누산기에 할당되고, 누산기는 순회 중 유지되므로 결국 최종 결과는 하나의 값이 된다. 이에 따라 누적 계산의 결과값이 reduce() 함수의 반환값이다.

형식

arr.reduce( callback [ , initialValue ] )
  • callback : 배열의 각 요소에 대해 실행할 함수 (리듀서(reducer) 함수)로 네 개의 인자( 누산기(acc), 현재값(cur), 현재 인덱스(idx), 원본 배열(src) )를 갖는다.
    • 누산기(accumulator) : 콜백의 반환값을 누적한다. 콜백의 이전 반환값이나 콜백의 첫 번째 호출인 initialValue인 경우에는 initialValue의 값을 가진다.
    • 현재 값(currentValue) : 처리할 현재 요소
    • 현재 인덱스(currentIndex) : 처리할 현재 요소의 인덱스 (initialValue인 경우 0 아니면 1부터 시작)
    • 원본배열(array) : reduce() 를 호출한 배열
  • initialValue : callback의 최초 호출에서 첫 번째 인수에 제공하는 값으로 초기값이 없으면 배열의 첫 번째 요소를 사용한다. (따라서 빈 배열에서 초기값이 없이 reduce()를 호출하면 오류 발생)

사용 예시

function sum(numbers){
    return numbers.reduce((total, num) => total + num, 0);
}
sum([1,2,3,4,5,6,7,8,9,10]);  //55

콜백함수로 ((total, num) => total + num)을, 두 번째 인자 initialValue로 초깃값 0 을 전달하였다. 첫 번째 순회로 초깃값 0을 total에 반환하고 이 결과값을 다시 첫 번째 인자에 전달하고 두 번째 인자에 배열(numbers)의 각 요솟값(1,2,3,...) 으로 순환 할당하면서 reduce() 함수를 실행한다.

순회 01회차  total : 0  ,  num  : 1 
순회 02회차  total : 0 + 1  ,  num : 2 
순회 03회차  total : 0 + 1 + 2  ,  num  : 3
...
순회 09회차  total : 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 +  8  ,  num  : 9
순회 10회차  total : 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 +  8 + 9  ,  num  : 10
순회 10회차 이후 최종 반환값 :  0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 +  8 + 9  + 10 으로 55

이 과정을 통해서 배열(numbers) 이 숫자로 변환되었다. 즉, reduce() 함수는 보통 배열을 특정 자료형으로 변환하는데 사용한다. 즉, 위 예제는 '합을 구하는 예제' 가 아니라 '배열을 숫자로 변환하는 예제' 인 것이다.

7.1에서 다룬 map() 으로 쿼리스트링 제거하는 예제에 reduce() 함수 활용

function parse(qs) { 
    const queryString = qs.substr(1);  // queryString = "banana=10&apple=20&orange=30" 
    const chunks = queryString.split('&');  // chunks = ['banana=10', 'apple=20', 'orange=30' ]
    return chunks
    .map((chunk) => {
    	const [ key, value ] = chunk.split('=');
        return { key, value };  // { key : 'banana', value : '10' } 형식
    })
    .reduce((result, item) => {
    	result[item.key] = item.value;  // result = { banana : '10' } 형식
        return result;
    }, {});  //초기값 = {}
}

parse("?banana=10&apple=20&orange=30");  //{ banana: '10', apple: '20', orange: '30' }

앞서 말했 듯이 reduce() 함수는 배열을 특정 자료형으로 변환하는데 사용한다. 이를 이용해서 7.1에서 다룬 map의 결과물로 배열이 반환되었는데 이 반환값을 객체로 변환했다.

순회 01회차  result : {} (초기값)  ,  item  :  { key : 'banana', value : '10' } 
순회 02회차  result : { banana : '10' }  ,  item  :  { key : 'apple', value : '20' }  
순회 03회차  result : { banana : '10', apple : '20' }  ,  item  : { key : 'orange', value : '30' } 
최종 반환값 :  { banana : '10', apple : '20', orange : '30'  }

{ key : ~ , value : ~ } 하는 배열 요소들을 item으로 두고 이를 각각 속성명 key를 키값으로, 속성명 value으로 값으로 누적 덧셈하여 하나의 객체로 반환하였다. 즉, 배열을 객체로 변환하는 예제이다.