Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 솔직후기
- 프리캐시 후기
- 용돈벌이
- Javascript
- error
- 재테크
- Array
- input focus
- ts 2882
- 자바스크립트
- FreeCash
- FreeCash 후기
- 배열
- 프론트엔드
- 앱테크추천
- 돈이돼지 후기
- 동버는앱
- 모듈을 찾을 수 없습니다.
- 키보드이슈
- 돈버는앱
- 돈버는어플
- NeXT
- TypeScript
- react
- 앱테크
- 해결 완료
- 캐시는내차지
- 삽질후기
- ios
- 앱테크 추천
Archives
- Today
- Total
우당탕탕 FE 개발자 이야기
[JavaScript] 배열 메서드 완벽 정리 (Array Method) 3탄 - 변환 본문
1탄에서는 배열 요소 추가/제거를, 2탄에서는 배열 탐색/검색을 다뤘습니다. 이번 3탄에서는 배열을 변환하는 가장 강력하고 자주 사용되는 메서드들을 정리해보겠습니다. 특히 map(), filter(), reduce()는 현대 자바스크립트 개발에서 필수적인 메서드입니다!
1. map() - 각 요소를 변환하여 새 배열 생성
map()은 배열의 모든 요소를 변환하여 새로운 배열을 만듭니다. 원본 배열은 변경되지 않습니다.
문법:
array.map(callback(element, index, array))
기본 예시:
const numbers = [1, 2, 3, 4, 5];
// 각 숫자를 2배로
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
console.log(numbers); // [1, 2, 3, 4, 5] (원본 유지)
// 각 숫자를 제곱
const squared = numbers.map(num => num ** 2);
console.log(squared); // [1, 4, 9, 16, 25]
실무 활용 예시:
// 1. API 응답 데이터 변환
const users = [
{ id: 1, firstName: '철수', lastName: '김' },
{ id: 2, firstName: '영희', lastName: '이' },
{ id: 3, firstName: '민수', lastName: '박' }
];
// 전체 이름으로 변환
const fullNames = users.map(user => `${user.lastName}${user.firstName}`);
console.log(fullNames); // ['김철수', '이영희', '박민수']
// 특정 속성만 추출
const userIds = users.map(user => user.id);
console.log(userIds); // [1, 2, 3]
// 2. 가격 데이터에 할인 적용
const products = [
{ name: '노트북', price: 1000000 },
{ name: '마우스', price: 30000 },
{ name: '키보드', price: 80000 }
];
// 10% 할인가 계산
const discountedProducts = products.map(product => ({
...product,
originalPrice: product.price,
discountedPrice: product.price * 0.9
}));
console.log(discountedProducts);
// [
// { name: '노트북', price: 1000000, originalPrice: 1000000, discountedPrice: 900000 },
// { name: '마우스', price: 30000, originalPrice: 30000, discountedPrice: 27000 },
// { name: '키보드', price: 80000, originalPrice: 80000, discountedPrice: 72000 }
// ]
// 3. HTML 요소 생성
const menuItems = ['홈', '소개', '서비스', '연락처'];
const menuHTML = menuItems.map(item => `<li>${item}</li>`).join('');
console.log(menuHTML);
// <li>홈</li><li>소개</li><li>서비스</li><li>연락처</li>
// 4. 날짜 포맷 변환
const dates = ['2024-01-15', '2024-02-20', '2024-03-10'];
const formattedDates = dates.map(date => {
const [year, month, day] = date.split('-');
return `${year}년 ${month}월 ${day}일`;
});
console.log(formattedDates);
// ['2024년 01월 15일', '2024년 02월 20일', '2024년 03월 10일']
주의사항:
// ❌ map()에서 조건부로 요소 제외하기 (안티패턴)
const numbers = [1, 2, 3, 4, 5];
const result = numbers.map(num => {
if (num % 2 === 0) return num * 2;
// 홀수는 undefined가 됨
});
console.log(result); // [undefined, 4, undefined, 8, undefined]
// ✅ 올바른 방법: filter()와 함께 사용
const result2 = numbers
.filter(num => num % 2 === 0)
.map(num => num * 2);
console.log(result2); // [4, 8]
2. filter() - 조건에 맞는 요소만 추출
filter()는 주어진 조건을 만족하는 모든 요소로 새로운 배열을 만듭니다.
문법:
array.filter(callback(element, index, array))
기본 예시:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 짝수만 필터링
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4, 6, 8, 10]
// 5보다 큰 숫자만
const largeNumbers = numbers.filter(num => num > 5);
console.log(largeNumbers); // [6, 7, 8, 9, 10]
실무 활용 예시:
// 1. 검색 기능 구현
const products = [
{ id: 1, name: '노트북', category: 'electronics', price: 1000000 },
{ id: 2, name: '마우스', category: 'electronics', price: 30000 },
{ id: 3, name: '책상', category: 'furniture', price: 150000 },
{ id: 4, name: '의자', category: 'furniture', price: 80000 }
];
// 카테고리별 필터링
const electronics = products.filter(p => p.category === 'electronics');
console.log(electronics);
// 가격대 필터링
const affordable = products.filter(p => p.price <= 100000);
console.log(affordable);
// 여러 조건 조합
const cheapElectronics = products.filter(p =>
p.category === 'electronics' && p.price < 50000
);
console.log(cheapElectronics); // [{ id: 2, name: '마우스', ... }]
// 2. 활성 사용자만 추출
const users = [
{ id: 1, name: '김철수', active: true, age: 25 },
{ id: 2, name: '이영희', active: false, age: 30 },
{ id: 3, name: '박민수', active: true, age: 28 }
];
const activeUsers = users.filter(user => user.active);
console.log(activeUsers); // 활성 사용자만
// 성인이면서 활성 사용자
const activeAdults = users.filter(user => user.active && user.age >= 18);
console.log(activeAdults);
// 3. 중복 제거 (unique values)
const numbers = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = numbers.filter((num, index, arr) =>
arr.indexOf(num) === index
);
console.log(uniqueNumbers); // [1, 2, 3, 4, 5]
// 4. 빈 값 제거
const inputs = ['hello', '', 'world', null, 'test', undefined, ''];
const validInputs = inputs.filter(input => input);
console.log(validInputs); // ['hello', 'world', 'test']
// 더 엄격한 검증
const cleanInputs = inputs.filter(input =>
input !== null && input !== undefined && input !== ''
);
console.log(cleanInputs); // ['hello', 'world', 'test']
map()과 filter() 함께 사용하기:
const users = [
{ name: '김철수', age: 17, city: '서울' },
{ name: '이영희', age: 25, city: '부산' },
{ name: '박민수', age: 30, city: '서울' },
{ name: '최지은', age: 22, city: '대구' }
];
// 서울에 사는 성인의 이름만 추출
const seoulAdultNames = users
.filter(user => user.city === '서울' && user.age >= 18)
.map(user => user.name);
console.log(seoulAdultNames); // ['박민수']
3. reduce() - 배열을 하나의 값으로 축약
reduce()는 배열의 모든 요소를 순회하며 하나의 값으로 축약(reduce)합니다. 가장 강력하지만 처음에는 어려울 수 있는 메서드입니다.
문법:
array.reduce(callback(accumulator, currentValue, index, array), initialValue)
- accumulator: 누적값
- currentValue: 현재 처리 중인 요소
- initialValue: 초기값 (선택사항이지만 항상 제공하는 것을 권장)
기본 예시:
const numbers = [1, 2, 3, 4, 5];
// 합계 구하기
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15
// 동작 과정:
// 1회: acc = 0, num = 1 → 0 + 1 = 1
// 2회: acc = 1, num = 2 → 1 + 2 = 3
// 3회: acc = 3, num = 3 → 3 + 3 = 6
// 4회: acc = 6, num = 4 → 6 + 4 = 10
// 5회: acc = 10, num = 5 → 10 + 5 = 15
// 곱하기
const product = numbers.reduce((acc, num) => acc * num, 1);
console.log(product); // 120
// 최댓값 찾기
const max = numbers.reduce((acc, num) => Math.max(acc, num));
console.log(max); // 5
실무 활용 예시:
// 1. 장바구니 총액 계산
const cart = [
{ name: '노트북', price: 1000000, quantity: 1 },
{ name: '마우스', price: 30000, quantity: 2 },
{ name: '키보드', price: 80000, quantity: 1 }
];
const totalPrice = cart.reduce((total, item) =>
total + (item.price * item.quantity), 0
);
console.log(totalPrice); // 1,140,000
// 2. 배열을 객체로 변환
const users = [
{ id: 1, name: '김철수' },
{ id: 2, name: '이영희' },
{ id: 3, name: '박민수' }
];
const userMap = users.reduce((acc, user) => {
acc[user.id] = user.name;
return acc;
}, {});
console.log(userMap);
// { 1: '김철수', 2: '이영희', 3: '박민수' }
// 3. 그룹화 (groupBy)
const students = [
{ name: '철수', grade: 'A' },
{ name: '영희', grade: 'B' },
{ name: '민수', grade: 'A' },
{ name: '지은', grade: 'C' },
{ name: '준호', grade: 'B' }
];
const groupedByGrade = students.reduce((acc, student) => {
if (!acc[student.grade]) {
acc[student.grade] = [];
}
acc[student.grade].push(student.name);
return acc;
}, {});
console.log(groupedByGrade);
// {
// A: ['철수', '민수'],
// B: ['영희', '준호'],
// C: ['지은']
// }
// 4. 배열 평탄화 (flatten)
const nested = [[1, 2], [3, 4], [5, 6]];
const flattened = nested.reduce((acc, arr) => acc.concat(arr), []);
console.log(flattened); // [1, 2, 3, 4, 5, 6]
// 5. 카운팅
const fruits = ['사과', '바나나', '사과', '오렌지', '바나나', '사과'];
const fruitCount = fruits.reduce((acc, fruit) => {
acc[fruit] = (acc[fruit] || 0) + 1;
return acc;
}, {});
console.log(fruitCount);
// { 사과: 3, 바나나: 2, 오렌지: 1 }
// 6. 파이프라인 구성 (여러 작업을 순차적으로)
const data = [1, 2, 3, 4, 5];
const result = data.reduce((acc, num) => {
// 짝수만 필터링하고 2배로 만든 후 합계
if (num % 2 === 0) {
return acc + (num * 2);
}
return acc;
}, 0);
console.log(result); // (2*2) + (4*2) = 4 + 8 = 12
// 7. 고유값 추출 (unique values)
const numbers = [1, 2, 2, 3, 4, 4, 5];
const unique = numbers.reduce((acc, num) => {
if (!acc.includes(num)) {
acc.push(num);
}
return acc;
}, []);
console.log(unique); // [1, 2, 3, 4, 5]
reduce()의 고급 활용:
// Promise 순차 실행
const asyncTasks = [task1, task2, task3];
asyncTasks.reduce((promise, task) =>
promise.then(result => task(result)),
Promise.resolve()
);
// 깊은 속성 접근
const obj = { a: { b: { c: { d: 'value' } } } };
const path = ['a', 'b', 'c', 'd'];
const value = path.reduce((acc, key) => acc[key], obj);
console.log(value); // 'value'
4. sort() - 배열 정렬
sort()는 배열의 요소를 정렬합니다. 주의: 원본 배열을 직접 수정합니다!
문법:
array.sort(compareFunction)
기본 예시:
// 문자열 정렬 (기본: 알파벳 순)
const fruits = ['바나나', '사과', '오렌지', '딸기'];
fruits.sort();
console.log(fruits); // ['딸기', '바나나', '사과', '오렌지'] (가나다 순)
// ❌ 숫자 정렬 주의! (기본 sort는 문자열로 변환하여 정렬)
const numbers = [10, 5, 40, 25, 1000, 1];
numbers.sort();
console.log(numbers); // [1, 10, 1000, 25, 40, 5] (문자열 순서!)
// ✅ 올바른 숫자 정렬
const numbers2 = [10, 5, 40, 25, 1000, 1];
// 오름차순
numbers2.sort((a, b) => a - b);
console.log(numbers2); // [1, 5, 10, 25, 40, 1000]
// 내림차순
numbers2.sort((a, b) => b - a);
console.log(numbers2); // [1000, 40, 25, 10, 5, 1]
실무 활용 예시:
// 1. 객체 배열 정렬
const products = [
{ name: '노트북', price: 1000000 },
{ name: '마우스', price: 30000 },
{ name: '키보드', price: 80000 },
{ name: '모니터', price: 300000 }
];
// 가격 오름차순
products.sort((a, b) => a.price - b.price);
console.log(products);
// 가격 내림차순
products.sort((a, b) => b.price - a.price);
// 이름 가나다 순
products.sort((a, b) => a.name.localeCompare(b.name));
console.log(products);
// 2. 날짜 정렬
const events = [
{ name: '회의', date: new Date('2024-03-15') },
{ name: '발표', date: new Date('2024-01-20') },
{ name: '워크샵', date: new Date('2024-02-10') }
];
// 날짜 오름차순 (가장 빠른 날짜부터)
events.sort((a, b) => a.date - b.date);
console.log(events);
// 3. 다중 조건 정렬
const students = [
{ name: '철수', grade: 'A', score: 95 },
{ name: '영희', grade: 'B', score: 85 },
{ name: '민수', grade: 'A', score: 90 },
{ name: '지은', grade: 'B', score: 88 }
];
// 등급순으로 정렬하고, 같은 등급이면 점수순
students.sort((a, b) => {
if (a.grade === b.grade) {
return b.score - a.score; // 점수 내림차순
}
return a.grade.localeCompare(b.grade); // 등급 오름차순
});
console.log(students);
// 4. 원본 유지하면서 정렬 (불변성)
const original = [3, 1, 4, 1, 5];
// 스프레드 연산자 사용
const sorted1 = [...original].sort((a, b) => a - b);
// slice() 사용
const sorted2 = original.slice().sort((a, b) => a - b);
console.log(original); // [3, 1, 4, 1, 5] (원본 유지)
console.log(sorted1); // [1, 1, 3, 4, 5]
한글 정렬:
const names = ['홍길동', '김철수', '이영희', '박민수'];
// localeCompare 사용 (한글 자모 순서 고려)
names.sort((a, b) => a.localeCompare(b, 'ko-KR'));
console.log(names); // ['김철수', '박민수', '이영희', '홍길동']
5. reverse() - 배열 순서 뒤집기
reverse()는 배열의 순서를 반대로 뒤집습니다. 주의: 원본 배열을 직접 수정합니다!
기본 예시:
const numbers = [1, 2, 3, 4, 5];
numbers.reverse();
console.log(numbers); // [5, 4, 3, 2, 1]
const fruits = ['사과', '바나나', '오렌지'];
fruits.reverse();
console.log(fruits); // ['오렌지', '바나나', '사과']
실무 활용 예시:
// 1. 최신순 정렬
const posts = [
{ id: 1, title: '첫 번째 글', date: '2024-01-01' },
{ id: 2, title: '두 번째 글', date: '2024-01-05' },
{ id: 3, title: '세 번째 글', date: '2024-01-10' }
];
// 날짜 오름차순 정렬 후 reverse로 최신순
const latestPosts = [...posts]
.sort((a, b) => new Date(a.date) - new Date(b.date))
.reverse();
console.log(latestPosts);
// 또는 sort에서 바로 내림차순
const latestPosts2 = [...posts]
.sort((a, b) => new Date(b.date) - new Date(a.date));
// 2. 문자열 뒤집기
const str = 'hello';
const reversed = str.split('').reverse().join('');
console.log(reversed); // 'olleh'
// 3. 원본 유지하면서 reverse
const original = [1, 2, 3, 4, 5];
const reversed2 = [...original].reverse();
console.log(original); // [1, 2, 3, 4, 5] (원본 유지)
console.log(reversed2); // [5, 4, 3, 2, 1]
메서드 체이닝 (Method Chaining)
여러 배열 메서드를 연결하여 강력한 데이터 처리 파이프라인을 만들 수 있습니다.
const orders = [
{ id: 1, product: '노트북', price: 1000000, quantity: 1, status: 'completed' },
{ id: 2, product: '마우스', price: 30000, quantity: 2, status: 'completed' },
{ id: 3, product: '키보드', price: 80000, quantity: 1, status: 'pending' },
{ id: 4, product: '모니터', price: 300000, quantity: 1, status: 'completed' },
{ id: 5, product: '헤드셋', price: 50000, quantity: 3, status: 'cancelled' }
];
// 완료된 주문의 총 매출액 계산
const totalRevenue = orders
.filter(order => order.status === 'completed') // 완료된 주문만
.map(order => order.price * order.quantity) // 각 주문의 총액 계산
.reduce((sum, amount) => sum + amount, 0); // 모두 합산
console.log(totalRevenue); // 1,360,000
// 가격대별 상품 목록 (10만원 이상/미만)
const categorizedProducts = orders
.map(order => ({
name: order.product,
totalPrice: order.price * order.quantity
}))
.sort((a, b) => b.totalPrice - a.totalPrice)
.reduce((acc, item) => {
const category = item.totalPrice >= 100000 ? 'premium' : 'standard';
if (!acc[category]) acc[category] = [];
acc[category].push(item.name);
return acc;
}, {});
console.log(categorizedProducts);
// {
// premium: ['노트북', '모니터', '헤드셋'],
// standard: ['마우스', '키보드']
// }
실전 예제: 데이터 분석
const sales = [
{ date: '2024-01', amount: 1000000, category: 'A' },
{ date: '2024-01', amount: 500000, category: 'B' },
{ date: '2024-02', amount: 1500000, category: 'A' },
{ date: '2024-02', amount: 800000, category: 'B' },
{ date: '2024-03', amount: 1200000, category: 'A' }
];
// 카테고리 A의 월별 평균 매출
const categoryAAverage = sales
.filter(sale => sale.category === 'A')
.map(sale => sale.amount)
.reduce((sum, amount, _, arr) => sum + amount / arr.length, 0);
console.log(categoryAAverage); // 1,233,333
// 월별 총 매출
const monthlyTotal = sales
.reduce((acc, sale) => {
if (!acc[sale.date]) acc[sale.date] = 0;
acc[sale.date] += sale.amount;
return acc;
}, {});
console.log(monthlyTotal);
// { '2024-01': 1500000, '2024-02': 2300000, '2024-03': 1200000 }
메서드 비교표
| 메서드 | 반환값 | 원본 변경 | 용도 |
| map() | 새 배열 | ❌ | 각 요소를 변환 |
| filter() | 새 배열 | ❌ | 조건에 맞는 요소만 추출 |
| reduce() | 단일 값 | ❌ | 배열을 하나의 값으로 축약 |
| sort() | 정렬된 배열 | ✅ | 배열 정렬 |
| reverse() | 뒤집힌 배열 | ✅ | 배열 순서 반전 |
성능 최적화 팁
// ❌ 비효율적: 여러 번 순회
const data = [1, 2, 3, 4, 5];
const result1 = data.filter(n => n % 2 === 0);
const result2 = result1.map(n => n * 2);
const result3 = result2.reduce((sum, n) => sum + n, 0);
// ✅ 효율적: 한 번에 처리
const result = data.reduce((sum, n) => {
if (n % 2 === 0) {
return sum + (n * 2);
}
return sum;
}, 0);
// 하지만 가독성을 위해 체이닝을 선택할 수도 있음
const result4 = data
.filter(n => n % 2 === 0)
.map(n => n * 2)
.reduce((sum, n) => sum + n, 0);
// 성능보다 코드 가독성이 중요한 경우가 많습니다!
실전 종합 예제
// 전자상거래 대시보드 데이터 처리
const transactions = [
{ id: 1, userId: 101, product: '노트북', amount: 1000000, date: '2024-01-15', status: 'completed' },
{ id: 2, userId: 102, product: '마우스', amount: 30000, date: '2024-01-16', status: 'completed' },
{ id: 3, userId: 101, product: '키보드', amount: 80000, date: '2024-01-17', status: 'completed' },
{ id: 4, userId: 103, product: '모니터', amount: 300000, date: '2024-01-18', status: 'pending' },
{ id: 5, userId: 102, product: '헤드셋', amount: 50000, date: '2024-01-19', status: 'completed' },
{ id: 6, userId: 104, product: '웹캠', amount: 70000, date: '2024-01-20', status: 'cancelled' }
];
// 1. 완료된 거래의 총 매출
const totalRevenue = transactions
.filter(t => t.status === 'completed')
.reduce((sum, t) => sum + t.amount, 0);
console.log(`총 매출: ${totalRevenue.toLocaleString()}원`);
// 2. 사용자별 구매 금액
const userPurchases = transactions
.filter(t => t.status === 'completed')
.reduce((acc, t) => {
acc[t.userId] = (acc[t.userId] || 0) + t.amount;
return acc;
}, {});
console.log('사용자별 구매 금액:', userPurchases);
// 3. 인기 상품 TOP 3
const productSales = transactions
.filter(t => t.status === 'completed')
.reduce((acc, t) => {
acc[t.product] = (acc[t.product] || 0) + t.amount;
return acc;
}, {});
const top3Products = Object.entries(productSales)
.sort((a, b) => b[1] - a[1])
.slice(0, 3)
.map(([product, amount]) => ({ product, amount }));
console.log('인기 상품 TOP 3:', top3Products);
// 4. 일별 거래 통계
const dailyStats = transactions
.reduce((acc, t) => {
if (!acc[t.date]) {
acc[t.date] = {
totalTransactions: 0,
totalAmount: 0,
statuses: {}
};
}
acc[t.date].totalTransactions++;
acc[t.date].totalAmount += t.amount;
acc[t.date].statuses[t.status] = (acc[t.date].statuses[t.status] || 0) + 1;
return acc;
}, {});
console.log('일별 통계:', dailyStats);
// 5. VIP 고객 (10만원 이상 구매)
const vipCustomers = transactions
.filter(t => t.status === 'completed')
.reduce((acc, t) => {
acc[t.userId] = (acc[t.userId] || 0) + t.amount;
return acc;
}, {})
.filter(amount => amount >= 100000);
console.log('VIP 고객:', Object.keys(vipCustomers));
마무리
배열을 변환하는 5가지 핵심 메서드를 알아봤습니다!
간단 정리:
- map(): 각 요소를 변환하여 새 배열 생성
- filter(): 조건에 맞는 요소만 추출
- reduce(): 배열을 하나의 값으로 축약
- sort(): 배열 정렬 (원본 변경!)
- reverse(): 배열 순서 뒤집기 (원본 변경!)
핵심 포인트:
- map(), filter(), reduce()는 원본을 변경하지 않습니다 (불변성)
- sort(), reverse()는 원본을 변경합니다 (주의!)
- 메서드 체이닝으로 강력한 데이터 처리 가능
- 가독성과 성능 사이의 균형을 고려하세요
이것으로 자바스크립트 배열 메서드 3부작이 완성되었습니다! 🎉
시리즈 전체 보기:
- [JavaScript] 배열 메서드 완벽 정리 (Array Method) 1탄 - 추가/제거
- [JavaScript] 배열 메서드 완벽 정리 (Array Method) 2탄 - 탐색/검색
- [JavaScript] 배열 메서드 완벽 정리 (Array Method) 3탄 - 변환(현재글)
'개발' 카테고리의 다른 글
| [Next Js - iOS/Safari Error] 키보드 올라올 때 화면 튕김 현상: 3시간 삽질 끝에 찾은 완벽 해결법 (0) | 2025.12.08 |
|---|---|
| [JavaScript] 배열 메서드 완벽 정리 (Array Method) 2탄 - 탐색/검색 (0) | 2025.12.03 |
| [JavaScript] 배열 메서드 완벽 정리 (Array Method) 1탄 - 추가/제거 (0) | 2025.12.03 |
| [NEXT/REACT] iOS WebView 영상 썸네일 백화 현상: 원인과 해결 방안 (0) | 2025.10.22 |
| Typescript Error(TS 2882) : 🤯 "globals.css 모듈을 찾을 수 없습니다" TypeScript 오류, 4단계 해결 여정 (0) | 2025.10.13 |