[JS] 배열 - reduce()

김하영·2022년 12월 20일
0

Javascipt

목록 보기
8/11
post-thumbnail

Array.prototype.reduce()

reduce() 메서드는 배열의 각 요소에 대해 주어진 리듀서 (reducer) 함수를 실행하고, 하나의 결과값을 반환합니다.

arr.reduce(callback[, initialValue])

파라미터

  1. callback function
  • accumulator : accumulator는 callback 함수의 반환값을 누적합니다.
  • currentValue : 배열의 현재 요소
  • index(Optional) : 배열의 현재 요소의 인덱스
  • array(Optional) : 호출한 배열

callback 함수의 반환 값은 accumulator에 할당되고 순회중 계속 누적되어 최종적으로 하나의 값을 반환합니다.

  1. initialValue(Optional)

최초 callback 함수 실행 시 accumulator 인수에 제공되는 값, 초기값을 제공하지 않을 경우 배열의 첫 번째 요소를 사용하고, 빈 배열에서 초기값이 없을 경우 에러가 발생합니다.

반환 값

배열을 순서대로 불러 각 요소에 대해 callback 함수를 실행한 결과를 누적한 값

예제

  1. 배열의 모든 값 (1부터 10까지) 더하기
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const sum = numbers.reduce((accumulator, currentNumber) => accumulator + currentNumber);

console.log('sum =', sum);
  1. 오브젝트 배열에서 원하는 항목의 값만 더하기
const list = [
	{
    	id: 0,
        value: '국어',
        grade: 90,
        isCompleted: true
    }, 
    {
    	id: 1,
        value: '영어',
        grade: 100,
        isCompleted: false
    },
    {
    	id: 2,
        value: '수학',
        grade: 60,
        isCompleted: false
    }
]

// initialValue 설정 X
const totalGrade = list.reduce((accumulator, currentObject) => {
	return accumulator + currentObject.grade
}, 0)


console.log('총 점수 :' totalGrade); // 250

작동 방식

예제 2에서 initialValue를 반드시 넣어줘야 하는 이유는 reduce의 작동 방식과 관련이 있습니다.

initialValue를 설정했느냐 안했느냐에 따라 콜백의 최초 호출 시의 accumulator와 currentValue가 달라집니다.

  • initialValue를 설정한 경우
callbackaccumulatorcurrentValuecurrentIndex
1번째 호출initialValue배열의 첫번째 요소0
  • initialValue를 설정하지 않은 경우
callbackaccumulatorcurrentValuecurrentIndex
1번째 호출배열의 첫번째 요소배열의 두번째 요소1

예를 들어

const number = [1, 2, 3, 4, 5];

function reducer(accumulator, currentValue, currentIndex) {
	const result = accumulator + currentValue;
    console.log(`accumulator: ${accumulator}, currentValue: ${currentValue}, currentIndex: ${currentIndex}, result: ${result}`);
    return result;
}

// initialValue가 없을 경우
number.reduce(reducer);

/*
	accumultor: 1, currnetValue: 2, currentIndex: 1, result: 3
    accumultor: 3, currnetValue: 3, currentIndex: 2, result: 6
    accumultor: 6, currnetValue: 4, currentIndex: 3, result: 10
    accumultor: 10, currnetValue: 5, currentIndex: 4, result: 15
*/


// initialValue가 있을 경우
number.reduce(reducer, 0);

/*
	accumultor: 0, currnetValue: 1, currentIndex: 0, result: 1
	accumultor: 1, currnetValue: 2, currentIndex: 1, result: 3
    accumultor: 3, currnetValue: 3, currentIndex: 2, result: 6
    accumultor: 6, currnetValue: 4, currentIndex: 3, result: 10
    accumultor: 10, currnetValue: 5, currentIndex: 4, result: 15
*/

initialValue가 없으면 배열의 2번째부터 계산이 시작되는데 배열이 비어있으면 당연히 TypeError가 발생합니다.

배열의 요소가 하나 뿐이면서 initialValue가 없는 경우, 또는 initialValue는 주어졌으나 배열이 비어있는 경우엔 계산할 필요가 없기 때문에 그 값을 callback 호출 없이 그대로 반환합니다.


위 작동방식을 근거로
예제 2번의 경우 initialValue가 없을 경우 첫 번째 콜백에서 TypeError가 발생하게 됩니다.

const list = [
	{
    	id: 0,
        value: '국어',
        grade: 90,
        isCompleted: true
    }, 
    {
    	id: 1,
        value: '영어',
        grade: 100,
        isCompleted: false
    },
    {
    	id: 2,
        value: '수학',
        grade: 60,
        isCompleted: false
    }
]

// initialValue 설정 X
const renderChecked = list.reduce((accumulator, currentObject) => {
	return accumulator + currentObject.grade
})

/* 첫번째 콜백 실행 시,
accumulator = {id: 0, value: '국어', grade: 90, isCompleted: true}
currentObject = {id: 01, value: '영어', grade: 100, isCompleted: true}
currentObject.grade = 90
accumulator + currentObject.grade = [Object]90 => typeError
*/

정리 : reduce()는 배열의 합을 구하거나, 배열 내 객체 값의 상태를 확인해서 갯수를 세는 데에 사용할 수 있다. (초기값을 설정해주지 않으면 에러 발생 위험이 있으니 주의하자.)

profile
호기심 많은 프론트엔드 주니어 💡

0개의 댓글