• ✏️ Reduce 함수

    2024. 1. 3.

    by. 서카츄

    Reduce는 배열의 모든 요소를 순회하면서 하나의 결과값을 만들어내는 배열 메서드이다

    "배열" 메서드 인게 중요!

     

     

     

    기본 문법

    // reduce의 기본 문법
    array.reduce((누적값, 현재값) => {
      // 계산 로직
      return 새로운누적값;
    }, 초기값);

     

     

     

    예시)

    // 1. 숫자 배열의 합계 구하기 
    const numbers = [1, 2, 3, 4, 5];
    
    const sum = numbers.reduce((acc, cur) => {
      console.log(`누적값(acc): ${acc}, 현재값(cur): ${cur}`);
      return acc + cur;
    }, 0);

     

     

     

     

    이 예시의 실행과정은 이렇게 된다.

    // 실행 과정:
    // 1단계: acc: 0, cur: 1 => 반환값: 1
    // 2단계: acc: 1, cur: 2 => 반환값: 3
    // 3단계: acc: 3, cur: 3 => 반환값: 6
    // 4단계: acc: 6, cur: 4 => 반환값: 10
    // 5단계: acc: 10, cur: 5 => 반환값: 15

     

     

     

     

    그래서 결국 sum의 결과값은 15가 된다.

    console.log(sum); // 15

     

     

     

     

     


     

    초기값을 주지 않는 경우 예시

    // 2. 초기값을 주지 않는 경우
    const numbers2 = [1, 2, 3, 4, 5];
    
    const sum2 = numbers2.reduce((acc, cur) => {
      console.log(`누적값(acc): ${acc}, 현재값(cur): ${cur}`);
      return acc + cur;
    }); // 초기값 없음

     

     

     

    실행 과정은 이렇게 진행된다.

    // 실행 과정:
    // 1단계: acc: 1, cur: 2 => 반환값: 3 (첫 번째 값이 초기값이 됨), 첫번째가 초기값이 되고 현재값은 2부터 시작함(두번째)
    // 2단계: acc: 3, cur: 3 => 반환값: 6
    // 3단계: acc: 6, cur: 4 => 반환값: 10
    // 4단계: acc: 10, cur: 5 => 반환값: 15

     

     

     

     

     


     

    다양한 활용 예시

     

    1. 최대값 찾기

    const numbers = [4, 1, 9, 2, 5];
    
    const max = numbers.reduce((acc, cur) => {
      console.log(`현재 누적값: ${acc}, 현재값: ${cur}, 비교 후 큰 값: ${Math.max(acc, cur)}`);
      return Math.max(acc, cur);
    }, 0);
    
    // 실행 과정:
    // 1단계: acc: 0, cur: 4 
    //    Math.max(0, 4) => 4가 더 크니까 4 반환
    
    // 2단계: acc: 4, cur: 1
    //    Math.max(4, 1) => 4가 더 크니까 4 반환
    
    // 3단계: acc: 4, cur: 9
    //    Math.max(4, 9) => 9가 더 크니까 9 반환
    
    // 4단계: acc: 9, cur: 2
    //    Math.max(9, 2) => 9가 더 크니까 9 반환
    
    // 5단계: acc: 9, cur: 5
    //    Math.max(9, 5) => 9가 더 크니까 9 반환
    
    console.log(max); // 9

     

     

     

     

     

     

    2. 객체 배열에서 특정 값 합계 구하기

    const cart = [
      { item: '사과', price: 1000 },
      { item: '바나나', price: 2000 },
      { item: '딸기', price: 3000 }
    ];
    
    const totalPrice = cart.reduce((acc, cur) => {
      return acc + cur.price;
    }, 0);
    
    console.log(totalPrice); // 6000

     

     

     

     

     

    3. 배열을 객체로 반환하기

    const fruits = ['apple', 'banana', 'apple', 'orange', 'banana'];
    
    const fruitCount = fruits.reduce((acc, cur) => {
      // 현재 과일이 없으면 1, 있으면 기존 값에 1을 더함
      acc[cur] = (acc[cur] || 0) + 1;
      return acc;
    }, {});
    
    console.log(fruitCount); 
    // { apple: 2, banana: 2, orange: 1 }

     

    더 상세히 적어보기

    const fruits = ['apple', 'banana', 'apple', 'orange', 'banana'];
    
    const fruitCount = fruits.reduce((acc, cur) => {
      console.log('현재 상태:', {
        누적객체: acc,
        현재과일: cur,
        해당과일현재개수: acc[cur],
      });
      
      acc[cur] = (acc[cur] || 0) + 1;
      
      console.log('업데이트 후:', acc);
      console.log('------------------------');
      
      return acc;
    }, {});  // 초기값으로 빈 객체 {}를 줌
    
    // 실행 과정:
    // 1단계: cur = 'apple'
    //   acc = {}
    //   acc['apple'] = (undefined || 0) + 1 = 1
    //   결과: { apple: 1 }
    
    // 2단계: cur = 'banana'
    //   acc = { apple: 1 }
    //   acc['banana'] = (undefined || 0) + 1 = 1
    //   결과: { apple: 1, banana: 1 }
    
    // 3단계: cur = 'apple'
    //   acc = { apple: 1, banana: 1 }
    //   acc['apple'] = (1 || 0) + 1 = 2
    //   결과: { apple: 2, banana: 1 }
    
    // 4단계: cur = 'orange'
    //   acc = { apple: 2, banana: 1 }
    //   acc['orange'] = (undefined || 0) + 1 = 1
    //   결과: { apple: 2, banana: 1, orange: 1 }
    
    // 5단계: cur = 'banana'
    //   acc = { apple: 2, banana: 1, orange: 1 }
    //   acc['banana'] = (1 || 0) + 1 = 2
    //   결과: { apple: 2, banana: 2, orange: 1 }
    
    // 다른 방식으로 작성한 동일한 로직
    function countFruits(fruits) {
      const result = {};
      
      for (const fruit of fruits) {
        if (result[fruit]) {
          // 이미 과일이 있으면 개수 증가
          result[fruit] += 1;
        } else {
          // 처음 나온 과일이면 1로 초기화
          result[fruit] = 1;
        }
      }
      
      return result;
    }
    
    // 조건부 연산자(||)를 사용하는 이유 설명
    const obj = {};
    console.log(obj.apple);        // undefined
    console.log(undefined || 0);   // 0 (undefined면 0 사용)
    console.log(1 || 0);          // 1 (값이 있으면 그 값 사용)

     

     

     

     

     

    4. 평균값 찾기

    const reviews = [
      { rating: 5, text: "아주 좋아요" },
      { rating: 4, text: "괜찮아요" },
      { rating: 5, text: "최고에요" }
    ];
    
    const averageRating = reviews.reduce((acc, cur) => {
      return acc + cur.rating;
    }, 0) / reviews.length;
    
    console.log(averageRating); // 4.666...

     

    const reviews = [
      { rating: 5, text: "아주 좋아요" },
      { rating: 4, text: "괜찮아요" },
      { rating: 5, text: "최고에요" }
    ];
    
    const averageRating = reviews.reduce((acc, cur) => {
      console.log('현재 상태:', {
        현재까지의합계: acc,
        현재리뷰: cur,
        현재평점: cur.rating
      });
      
      const sum = acc + cur.rating;
      console.log('더한 후:', sum);
      console.log('------------------------');
      
      return sum;
    }, 0) / reviews.length;  // 마지막에 리뷰 개수로 나눔
    
    // 실행 과정:
    // 1단계
    // acc (초기값) = 0
    // cur = { rating: 5, text: "아주 좋아요" }
    // 0 + 5 = 5
    
    // 2단계
    // acc = 5 (이전 단계의 결과)
    // cur = { rating: 4, text: "괜찮아요" }
    // 5 + 4 = 9
    
    // 3단계
    // acc = 9 (이전 단계의 결과)
    // cur = { rating: 5, text: "최고에요" }
    // 9 + 5 = 14
    
    // 최종 계산
    // 전체 합계 = 14
    // 리뷰 개수 = 3
    // 평균 = 14 / 3 = 4.666...
    
    // for 문으로 작성한 동일한 로직
    function calculateAverage(reviews) {
      let sum = 0;
      
      // 합계 계산
      for (const review of reviews) {
        sum += review.rating;
      }
      
      // 평균 계산
      return sum / reviews.length;
    }
    
    // 소수점 자리 제한하고 싶다면
    const roundedAverage = Number(averageRating.toFixed(1)); // 4.7
    
    // 다양한 활용 예시
    const reviewStats = reviews.reduce((acc, cur) => {
      return {
        sum: acc.sum + cur.rating,
        count: acc.count + 1,
        min: Math.min(acc.min, cur.rating),
        max: Math.max(acc.max, cur.rating)
      };
    }, { sum: 0, count: 0, min: 5, max: 0 });
    
    console.log({
      평균: reviewStats.sum / reviewStats.count,
      최저평점: reviewStats.min,
      최고평점: reviewStats.max
    });

    댓글