Christmas Pikachu JavaScript: reduce() 활용법
카테고리 없음

JavaScript: reduce() 활용법

ZI_CO 2024. 11. 1.

자바스크립트 배열 메서드 중에서도 가장 강력한 메서드를 뽑으라면, 단연 reduce()를 꼽을 수 있습니다.

하지만 범용적으로 쓰일 수 있는 만큼 이해하기도 쉽지 않아서 많은 초보 개발자들이 어려움을 겪곤 합니다.

이번 글에서는 reduce() 메서드의 기본 사용법과 실전 활용법을 쉽게 설명해보겠습니다.

reduce() 기본 사용법

reduce() 메서드는 배열의 각 요소에 대해 콜백 함수를 실행하여 누적된 하나의 결과값을 반환합니다.

기본 문법은 다음과 같습니다:

array.reduce(<콜백 함수>, <초기값>);

 

콜백 함수에는 총 4개의 인자가 전달됩니다:

  • accumulator: 이전 요소에서 누적된 결과값
  • currentValue: 현재 요소의 값
  • currentIndex: 현재 요소의 인덱스 (선택사항)
  • array: reduce()를 호출한 배열 자체 (선택사항)

대부분의 경우 첫 두 개의 인자만 사용되지만, 필요한 경우 나머지 인자를 활용하여 더 복잡한 연산을 수행할 수 있습니다.

초기값은 누적 계산을 시작할 때의 기본값입니다.

이를 설정하지 않으면 배열의 첫 번째 요소가 초기값으로 사용됩니다. 만약 초기값을 설정하지 않고 빈 배열에 대해 reduce()를 호출하게 되면 오류가 발생하므로 주의가 필요합니다.

reduce() 메서드로 누적 계산하기

가장 간단한 예시는 배열의 모든 숫자를 더하는 것입니다.

const numbers = [2, 4, 3, 1];
const sum = numbers.reduce((acc, num) => acc + num, 0); // 초기값을 0으로 설정하여 모든 요소를 더함
console.log(sum); // 10

 

여기서 acc는 누적자(Accumulator)로, 이전의 계산 결과를 가지고 있습니다. num은 현재 요소의 값을 의미합니다.

이 함수는 배열의 모든 요소를 순회하며 누적 계산을 수행합니다.

위의 코드는 reduce() 메서드를 사용하지 않고 반복문으로 작성할 수도 있지만, 코드가 더 장황해집니다

 

const numbers = [2, 4, 3, 1];
let sum = 0; // 합을 저장할 변수
for (const num of numbers) {
  sum += num; // 각 요소를 누적해서 더함
}
console.log(sum); // 10

 

reduce()를 사용하면, sum 변수를 const로 선언하여 값의 변경을 방지할 수 있기 때문에 더 견고한 코드를 작성할 수 있습니다.

최소값과 최대값 찾기

reduce()는 최소값이나 최대값을 찾는 데도 사용할 수 있습니다. 각 요소를 순회하면서 조건에 따라 누적값을 갱신합니다.

const numbers = [2, 4, 3, 1];
const min = numbers.reduce((min, num) => (min < num ? min : num), Number.MAX_VALUE); // 초기값을 Number.MAX_VALUE로 설정
console.log(min); // 1

const max = numbers.reduce((max, num) => (max > num ? max : num), Number.MIN_VALUE); // 초기값을 Number.MIN_VALUE로 설정
console.log(max); // 4

 

초기값을 지정하지 않으면 배열의 첫 번째 값이 기본값으로 사용됩니다. 만약 빈 배열에 reduce()를 사용하려 한다면 오류가 발생하므로 항상 초기값을 설정하는 습관을 가지는 것이 좋습니다.

객체의 개수 세기

reduce()는 배열 내 각 원소의 개수를 세는 데도 유용하게 사용됩니다. 예를 들어, 과일의 개수를 세어보겠습니다:

const fruits = ["apple", "banana", "apple", "orange", "banana", "apple"];
const fruitCounts = fruits.reduce((counter, fruit) => {
  // 객체에서 해당 과일이 이미 존재하는지 확인하고 존재하면 1을 더하고, 그렇지 않으면 1로 초기화
  counter[fruit] = (counter[fruit] || 0) + 1;
  return counter;
}, {}); // 초기값을 빈 객체로 설정하여 각 과일의 개수를 세기 시작함

console.log(fruitCounts); // { apple: 3, banana: 2, orange: 1 }

 

위 코드에서는 객체를 사용하여 각 과일의 개수를 저장하고 있습니다.

counter[fruit] = (counter[fruit] || 0) + 1을 통해 이미 존재하는 키는 값을 증가시키고, 없는 키는 1로 초기화하는 방식입니다.

배열 평탄화

reduce()를 사용하여 2차원 배열을 1차원 배열로 평탄화(flatten) 할 수 있습니다. 이는 중첩된 배열 구조를 단순화하는 데 유용합니다.

const nested = [
  [1, 2],
  [3, 4],
  [5, 6]
];
const flattened = nested.reduce((acc, val) => acc.concat(val), []); // 초기값을 빈 배열로 설정하여 중첩 배열을 합침
console.log(flattened); // [1, 2, 3, 4, 5, 6]

 

여기서는 concat()을 사용해 각 내부 배열을 누적 배열에 합쳐서 평탄화하고 있습니다.

최신 자바스크립트에서는 flat() 메서드를 사용해 더 간단하게 해결할 수도 있지만, reduce()를 사용하면

더욱 구체적인 컨트롤이 가능합니다.

데이터 그룹화

reduce()를 사용하면 데이터를 특정 기준으로 그룹화할 수 있습니다. 예를 들어, 사용자 배열을 국가별로 그룹화해보겠습니다:

const users = [
  { name: "John", age: 25, country: "US" },
  { name: "Jane", age: 30, country: "KR" },
  { name: "Robin", age: 22, country: "CA" },
  { name: "Doe", age: 13, country: "US" },
  { name: "Smith", age: 20, country: "KR" }
];

const usersByCountry = users.reduce((acc, user) => {
  const country = user.country;
  // 해당 국가가 아직 누적 객체에 없으면 빈 배열로 초기화
  if (!acc[country]) {
    acc[country] = [];
  }
  // 해당 국가 배열에 사용자 추가
  acc[country].push(user);
  return acc;
}, {}); // 초기값을 빈 객체로 설정하여 각 국가별 사용자 그룹화 시작

console.log(usersByCountry);

 

출력 결과는 다음과 같이 국가별로 사용자 목록을 나눈 객체가 됩니다

 

{
  US: [
    { name: "John", age: 25, country: "US" },
    { name: "Doe", age: 13, country: "US" }
  ],
  KR: [
    { name: "Jane", age: 30, country: "KR" },
    { name: "Smith", age: 20, country: "KR" }
  ],
  CA: [
    { name: "Robin", age: 22, country: "CA" }
  ]
}

 

이 예제에서는 사용자 객체의 country 속성을 기준으로 사용자들을 그룹화하고 있습니다. 초기값으로 빈 객체 {}를 설정하여 결과를 축적합니다.

원소 분류하기

특정 조건에 따라 배열의 요소를 여러 범주로 분류하고 싶을 때도 reduce()를 사용할 수 있습니다. 예를 들어 짝수와 홀수로 숫자 배열을 나누어보겠습니다

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const groupedNumbers = numbers.reduce(
  (acc, num) => {
    // 숫자가 짝수인지 확인하고 해당 배열에 추가
    if (num % 2 === 0) {
      acc.even.push(num);
    } else {
      acc.odd.push(num);
    }
    return acc;
  },
  { even: [], odd: [] } // 초기값으로 짝수와 홀수 배열을 각각 빈 배열로 설정
);

console.log(groupedNumbers); // { even: [2, 4, 6, 8], odd: [1, 3, 5, 7, 9] }

 

이 예제에서는 초기값으로 { even: [], odd: [] } 객체를 사용하여, reduce()를 통해 짝수와 홀수를 각각의 배열에 추가하고 있습니다.

마무리하며

지금까지 reduce() 메서드의 기본 사용법과 다양한 활용 사례를 살펴보았습니다.

reduce()는 매우 강력한 도구지만, 코드가 복잡해질 수 있으므로 꼭 필요한 경우에 사용하는 것이 좋습니다.

특히, reduce()를 남용하면 오히려 가독성을 해칠 수 있기 때문에, 적절한 상황에서만 사용하는 것이 중요합니다.

처음에는 헷갈리겠지만, 여러 번 사용해보면서 익숙해지면 다양한 문제를 효과적으로 해결할 수 있는 도구가 될 것입니다.

댓글