배열 메서드는 자바스크립트 코딩 테스트와 면접의 단골 주제입니다. 특히 map, filter, reduce는 함수형 프로그래밍의 기본이기도 해서, 동작 원리를 정확히 이해하고 있어야 합니다.

map — 변환

배열의 각 요소를 변환해서 같은 길이의 새 배열 을 반환합니다.

JS
const numbers = [1, 2, 3, 4, 5];

// 각 요소를 두 배로
const doubled = numbers.map((n) => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// 객체 배열에서 특정 필드만 추출
const users = [
  { name: "홍길동", age: 25 },
  { name: "이순신", age: 30 },
];
const names = users.map((user) => user.name);
console.log(names); // ["홍길동", "이순신"]

**주의 **: map은 항상 원본 배열과 같은 길이의 배열을 반환합니다. 필터링이 필요하면 filter를 써야 합니다.

filter — 필터링

조건에 맞는 요소만 모아 ** 새 배열 **을 반환합니다.

JS
const numbers = [1, 2, 3, 4, 5, 6];

// 짝수만 필터링
const evens = numbers.filter((n) => n % 2 === 0);
console.log(evens); // [2, 4, 6]

// falsy 값 제거
const mixed = [0, "hello", "", null, 42, undefined, "world"];
const truthy = mixed.filter(Boolean);
console.log(truthy); // ["hello", 42, "world"]

filter(Boolean) 패턴은 실무에서 정말 자주 쓰이니 기억해두면 좋습니다.

reduce — 누적

배열을 순회하면서 ** 하나의 값으로 축소 **합니다. 가장 범용적이지만 가장 어렵습니다.

JS
const numbers = [1, 2, 3, 4, 5];

// 합계
const sum = numbers.reduce((acc, cur) => acc + cur, 0);
console.log(sum); // 15

// 최댓값
const max = numbers.reduce((acc, cur) => Math.max(acc, cur), -Infinity);
console.log(max); // 5

// 빈도수 세기 — 면접 단골!
const fruits = ["사과", "바나나", "사과", "딸기", "바나나", "사과"];
const count = fruits.reduce((acc, fruit) => {
  acc[fruit] = (acc[fruit] || 0) + 1;
  return acc;
}, {});
console.log(count); // { 사과: 3, 바나나: 2, 딸기: 1 }

reduce로 map과 filter 구현하기

면접에서 종종 나오는 질문입니다.

JS
// reduce로 map 구현
const mapped = [1, 2, 3].reduce((acc, n) => {
  acc.push(n * 2);
  return acc;
}, []);

// reduce로 filter 구현
const filtered = [1, 2, 3, 4].reduce((acc, n) => {
  if (n % 2 === 0) acc.push(n);
  return acc;
}, []);

reduce는 만능이지만, map이나 filter로 충분한 경우에는 그것들을 쓰는 게 가독성이 좋습니다.

find — 첫 번째 매칭 요소

조건에 맞는 첫 번째 요소 를 반환합니다. 없으면 undefined입니다.

JS
const users = [
  { id: 1, name: "홍길동" },
  { id: 2, name: "이순신" },
  { id: 3, name: "김유신" },
];

const user = users.find((u) => u.id === 2);
console.log(user); // { id: 2, name: "이순신" }

// 없는 경우
const notFound = users.find((u) => u.id === 99);
console.log(notFound); // undefined

filter와의 차이: find는 하나만 반환, filter는 배열을 반환합니다.

findIndex

요소 대신 인덱스가 필요하면 findIndex를 사용합니다.

JS
const index = users.findIndex((u) => u.name === "이순신");
console.log(index); // 1

some — 하나라도 만족하는가

배열 요소 중 하나라도 조건을 만족하면 true를 반환합니다.

JS
const ages = [15, 22, 17, 30];

const hasAdult = ages.some((age) => age >= 18);
console.log(hasAdult); // true

// 빈 배열에서 some은 항상 false
console.log([].some(() => true)); // false

every — 모두 만족하는가

배열의 ** 모든 요소 **가 조건을 만족하면 true를 반환합니다.

JS
const ages = [20, 22, 25, 30];

const allAdults = ages.every((age) => age >= 18);
console.log(allAdults); // true

// 빈 배열에서 every는 항상 true (vacuous truth)
console.log([].every(() => false)); // true ← 주의!

[].every(() => false)true인 이유는 수학의 "공허한 참(vacuous truth)" 개념 때문입니다. 면접에서 이걸 아는지 물어보는 경우도 있습니다.

메서드 체이닝

실무에서는 이 메서드들을 체이닝해서 사용하는 경우가 많습니다.

JS
const products = [
  { name: "노트북", price: 1200000, inStock: true },
  { name: "키보드", price: 80000, inStock: true },
  { name: "마우스", price: 50000, inStock: false },
  { name: "모니터", price: 350000, inStock: true },
];

// 재고 있는 상품 이름을 가격순으로 정렬
const result = products
  .filter((p) => p.inStock)
  .sort((a, b) => a.price - b.price)
  .map((p) => p.name);

console.log(result); // ["키보드", "모니터", "노트북"]

비교 표

메서드반환값용도원본 변경
map새 배열 (같은 길이)변환X
filter새 배열 (같거나 짧음)필터링X
reduce단일 값누적/집계X
find요소 또는 undefined검색X
someboolean존재 확인X
everyboolean전체 검증X

자주 함께 쓰이는 배열 메서드

JS
// flatMap — map + flat
const sentences = ["Hello World", "Foo Bar"];
const words = sentences.flatMap((s) => s.split(" "));
console.log(words); // ["Hello", "World", "Foo", "Bar"]

// includes — 포함 여부
[1, 2, 3].includes(2); // true

// at — 음수 인덱스
[1, 2, 3].at(-1); // 3 (마지막 요소)

** 기억하기 **: map은 변환, filter는 필터링, reduce는 누적입니다. 이 세 가지의 차이를 확실히 알고 있으면 코딩 테스트에서 배열 문제를 만났을 때 어떤 메서드를 써야 할지 바로 판단할 수 있습니다.

댓글 로딩 중...