-
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 });
'📚 이론정리 > JS & TS' 카테고리의 다른 글
✏️ Instanceof 연산자 (0) 2024.01.19 ✏️ 객체 동적 접근 대괄호 표기법([]) (0) 2024.01.17 Map,Set (0) 2024.01.02 스크롤감지 getBoundingClientRect 메서드 (0) 2024.01.02 ✏️ 옵셔널체이닝(Optional-chaining)과 널리쉬퀄리싱(Nullish-coalescing) (0) 2023.11.03 댓글