Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

개발자공부일기

reduce의 다양한 쓰임새 본문

TIL(Today I Learned)

reduce의 다양한 쓰임새

JavaCPP 2024. 12. 6. 17:40

reduce는 복잡한 로직을 처리하거나 데이터를 축약해 새로운 구조를 생성할 때 매우 강력합니다. 아래에 다양한 예제들을 통해 활용 방법을 보여드리겠습니다.


1. 배열의 중첩 합계 구하기

중첩 배열의 모든 숫자를 더하는 예제입니다.

const nestedArray = [[1, 2, 3], [4, 5], [6, 7, 8, 9]];

const totalSum = nestedArray.reduce((accumulator, currentArray) => {
    const arraySum = currentArray.reduce((sum, num) => sum + num, 0);
    return accumulator + arraySum;
}, 0);

console.log(totalSum); // 45

동작:

  1. 외부 reduce는 각 중첩 배열(currentArray)을 순회합니다.
  2. 내부 reduce는 중첩 배열의 합을 계산합니다.
  3. 최종적으로 모든 합을 더해 반환합니다.

2. 데이터 그룹화

사용자 데이터를 나이에 따라 그룹화하는 예제입니다.

const users = [
    { name: "Alice", age: 25 },
    { name: "Bob", age: 30 },
    { name: "Charlie", age: 25 },
    { name: "David", age: 30 },
    { name: "Eve", age: 35 },
];

const groupedByAge = users.reduce((accumulator, user) => {
    const { age, name } = user;
    if (!accumulator[age]) {
        accumulator[age] = [];
    }
    accumulator[age].push(name);
    return accumulator;
}, {});

console.log(groupedByAge);
// {
//   25: ["Alice", "Charlie"],
//   30: ["Bob", "David"],
//   35: ["Eve"]
// }

동작:

  • 각 사용자의 나이(age)를 기준으로 그룹을 나누고, 이름(name)을 추가합니다.

3. 객체에서 값 추출

객체 배열에서 특정 키의 값을 모아 새로운 배열로 만드는 예제입니다.

const products = [
    { id: 1, name: "Laptop", price: 1500 },
    { id: 2, name: "Mouse", price: 20 },
    { id: 3, name: "Keyboard", price: 50 },
];

const productNames = products.reduce((accumulator, product) => {
    accumulator.push(product.name);
    return accumulator;
}, []);

console.log(productNames); // ["Laptop", "Mouse", "Keyboard"]

동작:

  • reduce를 사용해 각 제품의 name만 추출하여 새로운 배열에 추가합니다.

4. 중복 데이터의 빈도 계산

배열에서 중복된 값의 빈도를 계산하는 예제입니다.

const items = ["apple", "banana", "apple", "orange", "banana", "apple"];

const frequency = items.reduce((accumulator, item) => {
    accumulator[item] = (accumulator[item] || 0) + 1;
    return accumulator;
}, {});

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

동작:

  • 각 아이템을 키로 사용하고, 등장할 때마다 카운트를 증가시킵니다.

5. 배열의 교차값 추출

두 배열의 공통 요소를 추출하는 예제입니다.

const array1 = [1, 2, 3, 4];
const array2 = [3, 4, 5, 6];

const intersection = array1.reduce((accumulator, value) => {
    if (array2.includes(value)) {
        accumulator.push(value);
    }
    return accumulator;
}, []);

console.log(intersection); // [3, 4]

동작:

  • 첫 번째 배열의 요소를 순회하며, 두 번째 배열에 포함된 값만 결과 배열에 추가합니다.

6. 복잡한 데이터 변환

다양한 정보를 가진 객체 배열에서 새로운 형식의 객체를 생성하는 예제입니다.

const orders = [
    { orderId: 1, product: "Laptop", quantity: 2 },
    { orderId: 2, product: "Mouse", quantity: 5 },
    { orderId: 3, product: "Keyboard", quantity: 3 },
];

const summary = orders.reduce((accumulator, order) => {
    accumulator.totalOrders += 1;
    accumulator.totalQuantity += order.quantity;
    accumulator.products.push(order.product);
    return accumulator;
}, { totalOrders: 0, totalQuantity: 0, products: [] });

console.log(summary);
// {
//   totalOrders: 3,
//   totalQuantity: 10,
//   products: ["Laptop", "Mouse", "Keyboard"]
// }

동작:

  1. 각 주문 정보를 순회하며 총 주문 수와 총 수량을 계산합니다.
  2. 모든 제품 이름을 배열에 추가합니다.
 

코드에서 reduce의 마지막 부분에 있는 { totalOrders: 0, totalQuantity: 0, products: [] }는 초기값(initial value)입니다.

초기값의 역할

  1. reduce 함수의 시작점 설정:
    • reduce는 누적값(accumulator)을 기반으로 작업을 수행합니다.
    • 초기값이 없으면, 배열의 첫 번째 요소가 기본 누적값으로 사용됩니다.
    • 하지만 이 경우, 누적값이 객체로 설정되어야 하기 때문에 명시적으로
      { totalOrders: 0, totalQuantity: 0, products: [] }로 초기값을 제공하는 것입니다.
  2. 누적값의 데이터 타입 정의:
    • 초기값이 명시되지 않으면 reduce는 배열의 첫 번째 요소의 타입을 기반으로 데이터 타입을 결정합니다.
    • 초기값을 제공하면 명확하게 누적값 (accumulator)의 타입을 설정할 수 있습니다. 여기서는 객체 타입입니다.
  3. 초기값을 생략했을 때의 문제1. 첫 번째 요소가 누적값으로 사용됨
    • 배열의 첫 번째 요소(orders[0])가 누적값으로 설정됩니다.
    • accumulator.totalOrders와 같은 필드를 추가하려고 하면 오류가 발생합니다.
  4. 초기값이 없으면 예상치 못한 결과 발생
    • 만약 orders 배열이 비어 있다면, 초기값이 없을 때 reduce는 오류를 발생시킵니다.

7. 트리 구조 변환

트리 구조 데이터를 플랫(flat)한 배열로 변환하는 예제입니다.

const tree = [
    {
        id: 1,
        children: [
            { id: 2, children: [] },
            { id: 3, children: [{ id: 4, children: [] }] },
        ],
    },
];

const flattenTree = (nodes) =>
    nodes.reduce((accumulator, node) => {
        accumulator.push(node.id);
        if (node.children && node.children.length > 0) {
            accumulator.push(...flattenTree(node.children));
        }
        return accumulator;
    }, []);

const flatArray = flattenTree(tree);
console.log(flatArray); // [1, 2, 3, 4]

동작:

  1. 각 노드의 id를 플랫 배열에 추가합니다.
  2. 노드가 자식을 가지고 있으면 재귀 호출로 자식들을 플랫하게 만듭니다.

8. 문자열 분석

텍스트에서 각 단어의 등장 횟수를 계산하는 예제입니다.

const text = "hello world hello everyone hello world";
const words = text.split(" ");

const wordCount = words.reduce((accumulator, word) => {
    accumulator[word] = (accumulator[word] || 0) + 1;
    return accumulator;
}, {});

console.log(wordCount);
// { hello: 3, world: 2, everyone: 1 }

동작:

  1. 문자열을 공백으로 분리해 단어 배열을 생성합니다.
  2. 각 단어의 등장 횟수를 계산합니다.

이처럼 reduce는 간단한 합계 계산부터 복잡한 데이터 변환 및 구조화까지 다양한 용도로 사용할 수 있습니다. 데이터를 처리하고 결과를 축약하는 복잡한 작업이 필요할 때 특히 유용합니다.

'TIL(Today I Learned)' 카테고리의 다른 글

OSI 데이터링크계층  (0) 2024.12.09
OSI물리계층  (0) 2024.12.06
공통 테이블 표현식(CTE, Common Table Expression)  (0) 2024.12.05
자바스크립트에서 데이터 N중참조  (0) 2024.12.04
데이터베이스 정규화  (0) 2024.12.03