개발자공부일기
reduce의 다양한 쓰임새 본문
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
동작:
- 외부 reduce는 각 중첩 배열(currentArray)을 순회합니다.
- 내부 reduce는 중첩 배열의 합을 계산합니다.
- 최종적으로 모든 합을 더해 반환합니다.
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"]
// }
동작:
- 각 주문 정보를 순회하며 총 주문 수와 총 수량을 계산합니다.
- 모든 제품 이름을 배열에 추가합니다.
코드에서 reduce의 마지막 부분에 있는 { totalOrders: 0, totalQuantity: 0, products: [] }는 초기값(initial value)입니다.
초기값의 역할
- reduce 함수의 시작점 설정:
- reduce는 누적값(accumulator)을 기반으로 작업을 수행합니다.
- 초기값이 없으면, 배열의 첫 번째 요소가 기본 누적값으로 사용됩니다.
- 하지만 이 경우, 누적값이 객체로 설정되어야 하기 때문에 명시적으로
{ totalOrders: 0, totalQuantity: 0, products: [] }로 초기값을 제공하는 것입니다.
- 누적값의 데이터 타입 정의:
- 초기값이 명시되지 않으면 reduce는 배열의 첫 번째 요소의 타입을 기반으로 데이터 타입을 결정합니다.
- 초기값을 제공하면 명확하게 누적값 (accumulator)의 타입을 설정할 수 있습니다. 여기서는 객체 타입입니다.
- 초기값을 생략했을 때의 문제1. 첫 번째 요소가 누적값으로 사용됨
- 배열의 첫 번째 요소(orders[0])가 누적값으로 설정됩니다.
- accumulator.totalOrders와 같은 필드를 추가하려고 하면 오류가 발생합니다.
- 초기값이 없으면 예상치 못한 결과 발생
- 만약 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]
동작:
- 각 노드의 id를 플랫 배열에 추가합니다.
- 노드가 자식을 가지고 있으면 재귀 호출로 자식들을 플랫하게 만듭니다.
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 }
동작:
- 문자열을 공백으로 분리해 단어 배열을 생성합니다.
- 각 단어의 등장 횟수를 계산합니다.
이처럼 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 |