프로그래밍/Js

Array.reduce 여러가지 사용 사례

소행성왕자 2024. 8. 27. 09:19

사례 1 사용: 숫자 합산

reduce()의 가장 간단한 사용 사례 중 하나는 여러 숫자를 합산하는 것입니다.

정수 배열이 있고 총합을 구하고 싶다고 가정해 보겠습니다.

// 반복문 사용
const numbers = [1, 2, 3, 4, 5];
let sum=0;
for(let i=0; i<numbers.length; i++){
    sum += numbers[i];
}
console.log(sum);





// recude 사용
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc,curr)=>acc+curr, 0);
console.log(sum);

와우! 코드 한 줄만으로 배열의 모든 요소의 합을 계산했습니다.

어큐뮬레이터의 초기 값은 0으로 설정되고 각 반복에서 현재 요소를 어큐뮬레이터에 추가합니다.

시작 값을 제외하기로 선택하면 reduce는 배열의 첫 번째 항목만 사용합니다.

하지만 저는 항상 초기 값을 포함하는 경향이 있어서 읽기가 더 쉽습니다.

사용 사례 2: 배열 평면화

여러분은 여러 배열을 보면서 "이걸 하나의 배열로 합칠 수만 있다면 좋겠다"고 생각해 본 적이 있나요?

const numbers = [[1, 2], [3, 4], [5, 6]];
const flat = numbers.reduce((acc,curr)=>acc.concat(curr)  , []);
console.log(flat); // Output: [1, 2, 3, 4, 5, 6]

// concat 을 스프레드 연산자를 사용하여 현대적 코드로 바꿀수 있다.
const numbers = [[1, 2], [3, 4], [5, 6]];
const flat = numbers.reduce((acc,curr)=> [...acc, ...curr]  , []);
console.log(flat); // Output: [1, 2, 3, 4, 5, 6]


// ES10 함수 추가
const numbers = [[1, 2], [3, 4], [5, 6]];
const bb = numbers.flat();
console.log(aa); // [1, 2, 3, 4, 5, 6]

이 예에서 우리는 초기 어큐뮬레이터 값으로 빈 배열을 시작합니다.

그런 다음 각 반복에서 concat() 메서드를 사용하여 현재 하위 배열을 어큐뮬레이터에 연결합니다.

마지막에는 완벽하게 1차원 배열이 생깁니다. 

사례 3: 객체 그룹화

객체 배열이 있고, 이를 특정 속성을 기준으로 그룹화하려는 경우를 상상해 보세요.

reduce()는 이런 작업에 가장 적합한 도구입니다.

const people = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 25 },
  { name: 'Dave', age: 30 }
];

const groupedByAge = people.reduce((acc, curr) => {
  // 객체 속성 접근 방식 변경 및 배열 초기화에 단축 구문 사용
  (acc[curr.age] = acc[curr.age] || []).push(curr);
  return acc;
}, {});

console.log(groupedByAge);

/*
Output:
{
  '25': [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }],
  '30': [{ name: 'Bob', age: 30 }, { name: 'Dave', age: 30 }]
}
*/

이 경우, 우리는 객체를 초기 어큐뮬레이터 값으로 사용합니다.

우리는 어큐뮬레이터에 현재 age 에 대한 속성이 이미 있는지 확인합니다.

그렇지 않은 경우, 우리는 그 age에 대한 빈 배열을 만듭니다.

그런 다음, 우리는 현재 객체를 해당 age 배열에 푸시합니다. 마지막에는 키가 age이고 값이 그 age를 가진 사람들의 배열인 객체가 있습니다

(acc[curr.age] = acc[curr.age] || []).push(curr);

이 한 줄은 다음과 같은 작업을 수행합니다:

  • acc[curr.age]가 존재하지 않으면 빈 배열을 할당합니다.
  • 그 다음 push 메서드를 사용하여 현재 객체를 배열에 추가합니다.
  • 괄호로 묶어 표현식의 결과를 무시하고 push 연산만 수행합니다.

사용 사례 5: 발생 횟수 계산

배열에서 요소의 발생 횟수를 세어야 하는 적이 있나요? reduce()가 해결해 드립니다.

const fruits = ['apple', 'orange','orange','banana', 'apple', 'orange', 'orange','banana', 'apple'];

const fruitCounts = fruits.reduce((acc, curr) => {
  acc[curr] = (acc[curr] || 0) + 1;
  return acc;
}, {});

console.log(fruitCounts);

/*
Output:
{
  apple: 3, 
  orange: 4, 
  banana: 2
}
*/
}

이 예에서 우리는 빈 객체를 어큐뮬레이터로 초기화합니다.

배열의 각 과일에 대해 어큐뮬레이터 객체에 이미 속성으로 존재하는지 확인합니다.

그렇다면 카운트를 1씩 증가시키고 그렇지 않으면 1로 초기화합니다.

결과는 각 과일이 배열에 몇 번 나타나는지 알려주는 객체입니다.

acc[curr] = (acc[curr] || 0) + 1;

이 코드는 객체의 속성을 증가시키는 간결한 방법입니다. 각 부분을 분해해서 설명하겠습니다:

  1. acc[curr]
    • acc는 누산기(accumulator) 객체입니다.
    • curr는 현재 처리 중인 배열 요소(이 경우 과일 이름)입니다.
    • acc[curr]는 현재 과일의 카운트를 나타냅니다.
  2. (acc[curr] || 0)
    • 이 부분은 논리 OR 연산자(||)를 사용합니다.
    • 만약 acc[curr]가 falsy(undefined, null, 0 등)라면, 0을 사용합니다.
    • 만약 acc[curr]가 truthy라면, 그 값을 사용합니다.
  3. (acc[curr] || 0) + 1
    • 위에서 얻은 값(기존 카운트 또는 0)에 1을 더합니다.
  4. acc[curr] = ...
    • 계산된 새로운 카운트 값을 다시 acc[curr]에 할당합니다.

이 코드의 동작을 단계별로 풀어서 설명하면 다음과 같습니다:

if (acc[curr] === undefined) {
  // 처음 나온 과일이면
  acc[curr] = 1;
} else {
  // 이미 나온 과일이면
  acc[curr] = acc[curr] + 1;
}

 

예를 들어, 'apple'이 처음 나왔을 때와 그 이후에 나왔을 때의 동작은 다음과 같습니다:

  • 처음 'apple' 처리:
    acc['apple'] = (undefined || 0) + 1  acc['apple'] = 0 + 1  acc['apple'] = 1
  • 두 번째 'apple' 처리:
    acc['apple'] = (1 || 0) + 1  acc['apple'] = 1 + 1  acc['apple'] = 2

사용 사례 6: 고유한 값 생성

때로는 중복된 값이 포함된 배열이 있고, 고유한 값만 추출해야 할 수도 있습니다.

reduce()를 사용하면 이러한 작업을 손쉽게 수행할 수 있습니다.

const numbers = [1, 2, 3, 2, 4, 3, 5, 1, 6];
const bb = numbers.reduce((acc,curr)=>{
    if(!acc.includes(curr)) acc.push(curr);
    return acc;
}, []);
console.log(bb); // Output: [1, 2, 3, 4, 5, 6]

사례 7: 평균 계산

숫자 집합의 평균을 계산하고 싶으신가요? reduce()가 도와드리겠습니다!

const grades = [85, 90, 92, 88, 95];
const average = grades.reduce((acc, curr, index, arr) => {
    index === array.length - 1 ? (acc + curr) / array.length : acc + curr
}, 0);

console.log(average); // Output: 90

reduce 메서드의 콜백 함수는 네 개의 인자를 받을 수 있으며, 네 번째 인자가 원본 배열입니다.

reduce 메서드 콜백 함수의 인자들을 순서대로 설명하면 다음과 같습니다:

  1. accumulator (acc): 누산기. 콜백의 반환값을 누적합니다.
  2. currentValue (curr): 현재 처리 중인 배열의 요소.
  3. index (index): 현재 처리 중인 요소의 인덱스.
  4. array: reduce를 호출한 원본 배열.