JavaScript 배열 메서드: map, filter, reduce 완전 정복! 🚀
안녕, 친구들! 오늘은 JavaScript의 꿀잼 배열 메서드 삼총사인 map, filter, reduce에 대해 깊~게 파헤쳐볼 거야. 이 메서드들은 마치 재능넷에서 다양한 재능을 찾아 거래하듯이, 배열 데이터를 자유자재로 다룰 수 있게 해주는 강력한 도구들이지. 자, 그럼 우리 함께 이 신나는 JavaScript 여행을 떠나볼까? 😎
🎭 재능넷 TMI: 우리가 배울 이 메서드들은 마치 재능넷에서 다양한 재능을 찾고, 필터링하고, 조합하는 과정과 비슷해. 코딩의 세계에서도 이런 '재능'이 필요하다니, 재밌지 않아?
1. map() 메서드: 배열의 변신 마술사 🧙♂️
먼저 map() 메서드부터 알아볼게. 이 녀석은 마치 마법사처럼 배열의 각 요소를 새로운 모습으로 변신시켜주는 능력을 가졌어.
🎭 map()의 기본 사용법
const 원본배열 = [1, 2, 3, 4, 5];
const 변신배열 = 원본배열.map((요소) => 요소 * 2);
console.log(변신배열); // [2, 4, 6, 8, 10]
와우! 모든 숫자가 2배로 늘어났어. 마치 재능넷에서 자신의 재능을 업그레이드하는 것처럼 말이야.
🎨 map()으로 객체 배열 다루기
map()은 단순한 숫자 배열뿐만 아니라 복잡한 객체 배열도 자유자재로 다룰 수 있어.
const 사용자들 = [
{ 이름: '김코딩', 나이: 25 },
{ 이름: '박해커', 나이: 30 },
{ 이름: '이개발', 나이: 28 }
];
const 인사말 = 사용자들.map((사용자) => `안녕하세요, ${사용자.이름}님! ${사용자.나이}살이시네요.`);
console.log(인사말);
// ["안녕하세요, 김코딩님! 25살이시네요.", "안녕하세요, 박해커님! 30살이시네요.", "안녕하세요, 이개발님! 28살이시네요."]
이렇게 map()을 사용하면 복잡한 데이터도 쉽게 변형할 수 있어. 마치 재능넷에서 다양한 재능을 가진 사람들의 프로필을 한눈에 볼 수 있게 정리하는 것과 비슷하지?
🚀 map()의 고급 활용
map()은 단순히 배열의 요소를 변형하는 것 외에도 다양한 방식으로 활용할 수 있어.
const 숫자들 = [1, 4, 9, 16, 25];
const 제곱근과인덱스 = 숫자들.map((숫자, 인덱스) => ({
원본: 숫자,
제곱근: Math.sqrt(숫자),
인덱스: 인덱스
}));
console.log(제곱근과인덱스);
// [
// { 원본: 1, 제곱근: 1, 인덱스: 0 },
// { 원본: 4, 제곱근: 2, 인덱스: 1 },
// { 원본: 9, 제곱근: 3, 인덱스: 2 },
// { 원본: 16, 제곱근: 4, 인덱스: 3 },
// { 원본: 25, 제곱근: 5, 인덱스: 4 }
// ]
이렇게 map()을 사용하면 원본 데이터를 유지하면서도 새로운 정보를 추가할 수 있어. 마치 재능넷에서 사용자의 기본 정보에 추가적인 스킬 정보를 덧붙이는 것과 비슷하지?
💡 꿀팁: map() 메서드는 원본 배열을 변경하지 않고 새로운 배열을 반환해. 이는 데이터의 안전성을 지키면서도 유연하게 작업할 수 있게 해주는 큰 장점이야!
🎭 map()의 실전 활용 예제
자, 이제 map()을 실제 상황에서 어떻게 활용할 수 있는지 더 자세히 알아볼까?
const 상품목록 = [
{ 이름: '노트북', 가격: 1000000, 재고: 5 },
{ 이름: '스마트폰', 가격: 800000, 재고: 10 },
{ 이름: '태블릿', 가격: 500000, 재고: 7 }
];
const 할인상품 = 상품목록.map(상품 => ({
...상품,
할인가격: 상품.가격 * 0.9,
총액: 상품.가격 * 상품.재고
}));
console.log(할인상품);
// [
// { 이름: '노트북', 가격: 1000000, 재고: 5, 할인가격: 900000, 총액: 5000000 },
// { 이름: '스마트폰', 가격: 800000, 재고: 10, 할인가격: 720000, 총액: 8000000 },
// { 이름: '태블릿', 가격: 500000, 재고: 7, 할인가격: 450000, 총액: 3500000 }
// ]
이 예제에서는 원래 상품 정보에 10% 할인된 가격과 총 재고 가치를 추가했어. 이런 식으로 map()을 사용하면 복잡한 데이터 처리도 간단하게 할 수 있지.
🌈 map()의 창의적 활용
map()은 단순히 데이터 변환을 넘어서 창의적인 방식으로도 활용할 수 있어. 예를 들어, ASCII 아트를 만드는 데 사용할 수도 있지!
const 숫자배열 = [1, 2, 3, 4, 5];
const ASCII아트 = 숫자배열.map(num => '*'.repeat(num)).join('\n');
console.log(ASCII아트);
// *
// **
// ***
// ****
// *****
이렇게 map()을 사용하면 데이터를 시각적으로 표현하는 것도 가능해. 마치 재능넷에서 다양한 재능을 시각화하는 것처럼 말이야!
이 그림은 map() 메서드가 어떻게 작동하는지를 보여주고 있어. 원본 배열의 각 요소가 어떻게 새로운 값으로 변환되는지 한눈에 볼 수 있지? 이처럼 map()은 배열의 각 요소를 순회하면서 지정된 함수를 적용해 새로운 배열을 만들어내는 거야.
🤔 map()을 사용할 때 주의할 점
map()은 정말 유용한 메서드지만, 사용할 때 주의해야 할 점도 있어.
- map()은 항상 원본 배열과 같은 길이의 새 배열을 반환해. 만약 일부 요소만 변환하고 싶다면 filter()와 함께 사용하는 것이 좋아.
- map() 내부에서 원본 배열을 수정하지 않도록 주의해야 해. 예상치 못한 부작용이 발생할 수 있거든.
- 큰 배열에 대해 복잡한 연산을 수행하는 경우, 성능에 영향을 줄 수 있어. 이런 경우에는 for 루프를 사용하는 것이 더 효율적일 수 있지.
이런 점들을 주의하면서 map()을 사용하면, 정말 강력하고 유연한 도구로 활용할 수 있어!
2. filter() 메서드: 배열의 엄격한 문지기 🚧
이제 filter() 메서드에 대해 알아볼 차례야. 이 메서드는 마치 엄격한 문지기처럼 조건에 맞는 요소만 통과시켜 새로운 배열을 만들어내지.
🎭 filter()의 기본 사용법
const 숫자들 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const 짝수들 = 숫자들.filter((숫자) => 숫자 % 2 === 0);
console.log(짝수들); // [2, 4, 6, 8, 10]
짜잔! 짝수만 골라냈어. 마치 재능넷에서 특정 조건에 맞는 재능을 가진 사람들만 필터링하는 것과 비슷하지?
🕵️♂️ filter()로 복잡한 조건 다루기
filter()는 단순한 조건뿐만 아니라 복잡한 조건도 쉽게 다룰 수 있어.
const 사용자들 = [
{ 이름: '김코딩', 나이: 25, 직업: '개발자' },
{ 이름: '박해커', 나이: 30, 직업: '디자이너' },
{ 이름: '이개발', 나이: 28, 직업: '개발자' },
{ 이름: '최기획', 나이: 32, 직업: '기획자' }
];
const 젊은개발자들 = 사용자들.filter((사용자) => 사용자.나이 < 30 && 사용자.직업 === '개발자');
console.log(젊은개발자들);
// [{ 이름: '김코딩', 나이: 25, 직업: '개발자' }]
이렇게 여러 조건을 조합해서 원하는 데이터만 정확하게 골라낼 수 있어. 재능넷에서 특정 나이대의 특정 직업을 가진 사람들만 찾는 것과 비슷하지?
🚀 filter()의 고급 활용
filter()는 단순히 요소를 걸러내는 것 외에도 다양한 방식으로 활용할 수 있어.
const 문자열배열 = ['apple', 'banana', 'cherry', 'date', 'elderberry'];
const 긴단어들 = 문자열배열.filter((단어) => 단어.length > 5);
console.log(긴단어들); // ['banana', 'elderberry']
const 중복제거 = (배열) => 배열.filter((요소, 인덱스) => 배열.indexOf(요소) === 인덱스);
console.log(중복제거([1, 2, 2, 3, 4, 4, 5])); // [1, 2, 3, 4, 5]
이렇게 filter()를 사용하면 문자열의 길이를 기준으로 필터링하거나, 심지어 배열에서 중복된 요소를 제거하는 것도 가능해. 마치 재능넷에서 특정 기준을 만족하는 재능만 골라내거나, 중복된 재능 등록을 방지하는 것과 비슷하지?
💡 꿀팁: filter() 메서드도 map()과 마찬가지로 원본 배열을 변경하지 않아. 이는 원본 데이터의 무결성을 유지하면서 필요한 데이터만 추출할 수 있게 해주는 큰 장점이야!
🎭 filter()의 실전 활용 예제
자, 이제 filter()를 실제 상황에서 어떻게 활용할 수 있는지 더 자세히 알아볼까?
const 상품목록 = [
{ 이름: '노트북', 가격: 1000000, 재고: 5 },
{ 이름: '스마트폰', 가격: 800000, 재고: 0 },
{ 이름: '태블릿', 가격: 500000, 재고: 2 },
{ 이름: '이어폰', 가격: 200000, 재고: 10 }
];
const 구매가능상품 = 상품목록.filter(상품 => 상품.재고 > 0 && 상품.가격 <= 800000);
console.log(구매가능상품);
// [
// { 이름: '태블릿', 가격: 500000, 재고: 2 },
// { 이름: '이어폰', 가격: 200000, 재고: 10 }
// ]
이 예제에서는 재고가 있고 가격이 80만원 이하인 상품만 필터링했어. 이런 식으로 filter()를 사용하면 복잡한 조건에 맞는 데이터를 쉽게 추출할 수 있지.
🌈 filter()의 창의적 활용
filter()는 단순히 데이터 필터링을 넘어서 창의적인 방식으로도 활용할 수 있어. 예를 들어, 소수(Prime Number)를 찾는 데 사용할 수도 있지!
const 소수찾기 = (최대값) => {
return Array.from({ length: 최대값 - 1 }, (_, i) => i + 2).filter((num) => {
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) return false;
}
return true;
});
};
console.log(소수찾기(20)); // [2, 3, 5, 7, 11, 13, 17, 19]
이렇게 filter()를 사용하면 복잡한 수학적 개념도 간단하게 구현할 수 있어. 마치 재능넷에서 특별한 재능을 가진 사람들을 찾아내는 것처럼 말이야!
이 그림은 filter() 메서드가 어떻게 작동하는지를 보여주고 있어. 원본 배열에서 조건(여기서는 짝수)에 맞는 요소만 새로운 배열로 필터링되는 과정을 볼 수 있지? 이처럼 filter()는 배열의 각 요소를 순회하면서 지정된 조건을 만족하는 요소만을 새로운 배열에 포함시키는 거야.
🤔 filter()를 사용할 때 주의할 점
filter()는 정말 유용한 메서드지만, 사용할 때 주의해야 할 점도 있어.
- filter()는 항상 새로운 배열을 반환해. 따라서 메모리 사용량에 주의해야 해, 특히 큰 배열을 다룰 때는 더욱 그래.
- filter() 내부에서 원본 배열을 수정하지 않도록 주의해야 해. 예상치 못한 결과가 나올 수 있거든.
- 복잡한 객체를 필터링할 때는 깊은 복사(deep copy)를 고려해야 할 수도 있어. 그렇지 않으면 원본 객체가 변경될 수 있어.
- filter()는 'truthy' 값을 반환하는 모든 요소를 포함시켜. 이 점을 잘 이해하고 사용해야 해.
이런 점들을 주의하면서 filter()를 사용하면, 데이터를 정확하고 효율적으로 필터링할 수 있어!