JavaScript 배열 메서드: map, filter, reduce 완전 정복! 🚀

콘텐츠 대표 이미지 - 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() 메서드 시각화 1 2 3 2 4 6 x2 변환

이 그림은 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() 메서드 시각화 1 2 3 4 2 4 짝수 필터링

이 그림은 filter() 메서드가 어떻게 작동하는지를 보여주고 있어. 원본 배열에서 조건(여기서는 짝수)에 맞는 요소만 새로운 배열로 필터링되는 과정을 볼 수 있지? 이처럼 filter()는 배열의 각 요소를 순회하면서 지정된 조건을 만족하는 요소만을 새로운 배열에 포함시키는 거야.

🤔 filter()를 사용할 때 주의할 점

filter()는 정말 유용한 메서드지만, 사용할 때 주의해야 할 점도 있어.

  • filter()는 항상 새로운 배열을 반환해. 따라서 메모리 사용량에 주의해야 해, 특히 큰 배열을 다룰 때는 더욱 그래.
  • filter() 내부에서 원본 배열을 수정하지 않도록 주의해야 해. 예상치 못한 결과가 나올 수 있거든.
  • 복잡한 객체를 필터링할 때는 깊은 복사(deep copy)를 고려해야 할 수도 있어. 그렇지 않으면 원본 객체가 변경될 수 있어.
  • filter()는 'truthy' 값을 반환하는 모든 요소를 포함시켜. 이 점을 잘 이해하고 사용해야 해.

이런 점들을 주의하면서 filter()를 사용하면, 데이터를 정확하고 효율적으로 필터링할 수 있어!

3. reduce() 메서드: 배열의 만능 요리사 👨‍🍳

마지막으로 reduce() 메서드를 알아볼 차례야. 이 메서드는 마치 만능 요리사처럼 배열의 요소들을 다양한 방식으로 조합해 하나의 결과값을 만들어내지.

🎭 reduce()의 기본 사용법

const 숫자들 = [1, 2, 3, 4, 5];
const 합계 = 숫자들.reduce((누적값, 현재값) => 누적값 + 현재값, 0);
console.log(합계); // 15

와! 모든 숫자를 더해서 하나의 값으로 만들었어. 마치 재능넷에서 여러 사람의 재능을 모아 하나의 프로젝트를 완성하는 것과 비슷하지?

🧮 reduce()로 복잡한 연산 수행하기

reduce()는 단순한 덧셈 외에도 다양한 복잡한 연산을 수행할 수 있어.

const 투표결과 = ['김후보', '이후보', '박후보', '김후보', '이후보', '김후보'];
const 투표집계 = 투표결과.reduce((집계, 후보) => {
  집계[후보] = (집계[후보] || 0) + 1;
  return 집계;
}, {});
console.log(투표집계);
// { '김후보': 3, '이후보': 2, '박후보': 1 }

이렇게 reduce()를 사용하면 복잡한 데이터 구조도 쉽게 만들 수 있어. 재능넷에서 다양한 재능의 인기도를 집계하는 것과 비슷하지?

🚀 reduce()의 고급 활용

reduce()는 정말 다재다능해서 map()이나 filter()의 기능도 대신할 수 있어!

const 숫자배열 = [1, 2, 3, 4, 5];

// map 기능 구현
const 제곱배열 = 숫자배열.reduce((결과, 숫자) => {
  결과.push(숫자 * 숫자);
  return 결과;
}, []);
console.log(제곱배열); // [1, 4, 9, 16, 25]

// filter 기능 구현
const 짝수배열 = 숫자배열.reduce((결과, 숫자) => {
  if (숫자 % 2 === 0) 결과.push(숫자);
  return 결과;
}, []);
console.log(짝수배열); // [2, 4]

이렇게 reduce()를 사용하면 다른 배열 메서드들의 기능도 구현할 수 있어. 마치 재능넷에서 한 사람이 여러 가지 재능을 가지고 다양한 역할을 수행하는 것과 비슷하지?

💡 꿀팁: reduce()는 초기값을 설정할 수 있어. 초기값을 제공하면 배열이 비어있을 때도 안전하게 작동하고, 원하는 데이터 타입으로 결과를 만들 수 있어!

🎭 reduce()의 실전 활용 예제

자, 이제 reduce()를 실제 상황에서 어떻게 활용할 수 있는지 더 자세히 알아볼까?

const 주문목록 = [
  { 상품: '노트북', 가격: 1000000, 수량: 2 },
  { 상품: '마우스', 가격: 20000, 수량: 5 },
  { 상품: '키보드', 가격: 50000, 수량: 3 }
];

const 주문분석 = 주문목록.reduce((결과, 주문) => {
  결과.총액 += 주문.가격 * 주문.수량;
  결과.총수량 += 주문.수량;
  if (주문.가격 * 주문.수량 > 결과.최고가주문.금액) {
    결과.최고가주문 = { 상품: 주문.상품, 금액: 주문.가격 * 주문.수량 };
  }
  return 결과;
}, { 총액: 0, 총수량: 0, 최고가주문: { 상품: '', 금액: 0 } });

console.log(주문분석);
// {
//   총액: 2150000,
//   총수량: 10,
//   최고가주문: { 상품: '노트북', 금액: 2000000 }
// }

이 예제에서는 주문 목록을 분석해서 총액, 총 수량, 그리고 가장 비싼 주문을 한 번에 계산했어. 이런 식으로 reduce()를 사용하면 복잡한 데이터 분석도 한 번의 순회로 효율적으로 수행할 수 있지.

🌈 reduce()의 창의적 활용

reduce()는 정말 다재다능해서 아주 창의적인 방식으로도 활용할 수 있어. 예를 들어, 배열을 사용해 간단한 상태 관리 시스템을 만들 수도 있지!