[JavaScript] Array.prototype.reduce()

현채은·2025년 2월 4일
post-thumbnail

reduce 함수란?


reduce()는 JavaScript 배열 메서드로, 배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환하는 함수입니다. 이 과정에서 기존 배열은 수정되지 않고 유지됩니다.

언제 사용하나요?

  • 배열에서 데이터를 가공하고 싶은 경우
  • 배열에서 데이터를 객체로 변환하고 싶은 경우

사용방법

💡 reduce() 함수를 사용하는 경우 원본 배열은 변경되지 않는다는 점을 꼭 기억해주세요!

기본 문법

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

// callback : 배열의 각 요소에 대해 실행할 리듀서 함수
  arr.reduce(callback[, initialValue])
// 네 가지 인수를 풀어 사용하는 경우
  arr.reduce((accumulator, currentValue, currentIndex, array) => { 
	return accumulator + currentValue;
}, initialValue);

👩🏻‍🏫  리듀서(reducer) 함수가 무엇인가요?

reduce() 메서드 자체에 가지고 있는 콜백함수입니다.

  • initialValue : callback의 최초 호출에서 첫번째 인수(accumulator)에 제공하는 값이며, 초기값이 없으면 배열의 첫번째 요소를 사용합니다.
  • 해당 리듀서(reducer) 함수는 네 개의 인자를 가질 수 있습니다.
    • accumulator : reduce에서 정해준 초기값(initialValue)이 들어가고, 계산이 진행되면서 업데이트 되는 값입니다.
      • 예를 들어, 숫자를 더하는 경우 **지금까지 더한 총 합**이 들어갑니다.
    • currentValue : 배열에서 현재 처리할 요소입니다.
    • currentIndex : 배열에서 현재 처리할 요소의 인덱스입니다.
      • 초기값(initialValue)을 제공한 경우 0, 아니면 1부터 시작합니다.
    • array : 원본 배열입니다.

🔎  쉽게 접근해보기

  1. 상자(accumulator)를 하나 준비합니다. (이 상자는 계산 결과를 저장하는 곳입니다.)
    1. 초기값(initialValue)이 존재한다면 상자의 값은 초기값으로 시작합니다.
  2. 배열의 요소를 하나씩 돌면서(currentValue), 새로운 값을 상자(accumulator)에 더하거나 변경합니다.
  3. 배열(array)의 모든 요소를 다 순회하면, 상자에 최종 결과(accumulator)가 남아있습니다.

사용 예시


  1. numbers 배열에서 요소의 총 합을 구하고 싶은 경우
const numbers = [1, 2, 3, 4, 5];

// reduce 사용
const sum = numbers.reduce((accumulator, currentValue) => {
  return accumulator + currentValue;
}, 0); // 초기값 0 (initialValue)

console.log("합계:", sum); // 출력: 합계: 15
  • numbers : 원본 배열 ( reduce 함수를 적용해도 변경되지 않습니다. )
    • ex. [1, 2, 3, 4, 5]
  • currentValue : numbers 배열의 각 요소
    • ex. 1, 2, 3, 4, 5
  • accumulator + currentValue
    • 🔄 동작 방식
      • 첫 번째 순회: 0 + 1 = 1
        • accumulator의 초기값이 0 → 1로 업데이트
      • 두 번째 순회: 1 + 2 = 3
        • accumulator의 값이 13로 업데이트
      • 세 번째 순회: 3 + 3 = 6
        • accumulator의 값이 36로 업데이트
      • 네 번째 순회: 6 + 4 = 10
        • accumulator의 값이 610로 업데이트
      • 다섯 번째 순회: 10 + 5 = 15
        • accumulator의 값이 1015로 업데이트
  • sum
    • ex. 15 (배열의 총 합)
  1. numbers 배열에서 최대값을 구하고 싶은 경우
const numbers = [3, 5, 1, 8, 2];

// reduce 사용
const max = numbers.reduce((accumulator, currentValue) => {
  return Math.max(accumulator, currentValue);
});

console.log("최대값:", max); // 출력: 최대값: 8
  • numbers : 원본 배열 ( reduce 함수를 적용해도 변경되지 않습니다. )
    • ex. [3, 5, 1, 8, 2]
  • currentValue : numbers 배열의 각 요소
    • ex. 3, 5, 1, 8, 2
  • Math.max(accumulator, currentValue)
    • 🔄 동작 방식
      • 첫 번째 비교: 3 vs 5
        • 최대값: 5 (accumulator 업데이트)
      • 두 번째 비교: 5 vs 1
        • 최대값: 5 (기존 값이 더 크기 때문에 값 유지)
      • 세 번째 비교: 5 vs 8 → 최대값: 8
        • 최대값: 8 (accumulator 업데이트)
      • 네 번째 비교: 8 vs 2 → 최대값: 8
        • 최대값: 8 (기존 값이 더 크기 때문에 값 유지)
  • max
    • ex. 8 (최대값)

한 걸음 더 나아가기


앞서 학습했던 map, filter 메서드 모두 기억하시나요? 👩🏻‍🏫

map,filter 함수로 구현할 수 있는 기능들은 모두 reduce 함수로 구현 가능합니다.

💻 코드로 직접 알아보기

  1. map reduce로 구현해보기
  • 배열 요소를 2배로 변환하기 (mapreduce)
const numbers = [1, 2, 3, 4, 5];

// map을 사용한 방식
const doubledWithMap = numbers.map((num) => num * 2);

// reduce로 동일한 결과 구현
const doubledWithReduce = numbers.reduce((acc, num) => {
  acc.push(num * 2);
  return acc;
}, []);

console.log("map:", doubledWithMap);      // 출력: [2, 4, 6, 8, 10]
console.log("reduce:", doubledWithReduce); // 출력: [2, 4, 6, 8, 10]
  1. filter reduce로 구현
  • 배열 요소 중 짝수만 반환하기 (filterreduce)
const numbers = [1, 2, 3, 4, 5];

// filter를 사용한 방식
const evenWithFilter = numbers.filter((num) => num % 2 === 0);

// reduce로 동일한 결과 구현
const evenWithReduce = numbers.reduce((acc, num) => {
  if (num % 2 === 0) acc.push(num);
  return acc;
}, []);

console.log("filter:", evenWithFilter);      // 출력: [2, 4]
console.log("reduce:", evenWithReduce);      // 출력: [2, 4]

TMI

  • reduce()는 Array 객체 ProtoType에 정의되어 있는 고차 함수입니다.
  • reduce()는 배열의 값을 한개로 감소 시키는 특징을 가지고 있습니다.

즉, reduce()는 배열의 각 요소에 대해 callback을 실행하며 단 1개의 출력 결과를 만듭니다. 그래서 "줄이다"의 의미인 reduce라는 이름을 얻었습니다.

profile
개발 기록 공간

0개의 댓글