C
JavaScript/객체배열/Lesson 12

배열 메서드 — *함수형의 핵심*

1시간·theory
이 챕터
2/2

배열 메서드 — *함수형의 핵심*

🎯 이 lesson 을 읽고 나면

이 lesson 을 다 읽고 나면 아래 3가지를 자신 있게 할 수 있습니다.

  • ✅ map · filter · reduce · find · some · every 체이닝
  • ✅ sort 가 원본 변경 — toSorted (ES2023) 로 불변
  • ✅ flat · flatMap · Array.from 활용

학습 목표를 체크리스트로 두고 다 답할 수 있게 되면 lesson 을 닫으세요.

필수 5가지 메서드

핵심 한 줄

JS 배열의 함수형 메서드map·filter·reduce·find·some/every — 만 익혀도 반복문 90% 가 사라집니다. 함수형 사고 의 시작.

map — 각 원소 변환

javascript
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);    // 각 원소에 *2
console.log(doubled);    // [2, 4, 6, 8, 10]
console.log(numbers);    // [1, 2, 3, 4, 5]   ← 원본 그대로! (새 배열 반환)

const users = [{name:"홍"}, {name:"이"}];
const names = users.map(u => u.name);       // 각 객체에서 name 만 추출
console.log(names);      // ["홍", "이"]

옛 코드: for 루프 + push. 모던: .map() 한 줄.

filter — 조건 통과만

javascript
const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter(n => n % 2 === 0);   // 짝수만 남김
console.log(evens);     // [2, 4]

const users = [
    { name: 'A', age: 20 },
    { name: 'B', age: 15 },
    { name: 'C', age: 30 }
];
const adults = users.filter(u => u.age >= 18);
console.log(adults);    // [ { name: 'A', age: 20 }, { name: 'C', age: 30 } ]

reduce — 하나로 줄이기

javascript
const numbers = [1, 2, 3, 4, 5];
// acc: 누적값(시작 0), n: 현재 원소
const sum = numbers.reduce((acc, n) => acc + n, 0);
console.log(sum);   // 15   ← 0 + 1 + 2 + 3 + 4 + 5

// 🧮 누적기로 객체도 만들 수 있음 — 카테고리별 개수 세기
const items = [
    { category: 'food' },  { category: 'drink' },
    { category: 'food' },  { category: 'food' }
];
const byCategory = items.reduce((acc, item) => {
    acc[item.category] = (acc[item.category] || 0) + 1;
    return acc;
}, {});
console.log(byCategory);   // { food: 3, drink: 1 }

reducemap·filter 도 다 만들 수 있는 가장 강력한 메서드. 처음엔 헷갈리지만 익숙해지면 강력.

find — 첫 매칭

javascript
const users = [{id:1, name:"홍"}, {id:2, 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   ← 못 찾으면 undefined

filter모든 매칭, find첫 번째만.

some / every — 진위 검사

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

console.log(numbers.some(n => n > 3));    // true   ← 하나라도 만족? (4, 5 가 만족)
console.log(numbers.every(n => n > 0));   // true   ← 모두 만족? (전부 양수)
console.log(numbers.every(n => n > 3));   // false  ← 1, 2, 3 이 못 넘김

if (array.find(...)) 보다 if (array.some(...))의도 명확.

체이닝 — 조립

javascript
const orders = [
    { id: 1, amount: 10000, status: 'PAID' },
    { id: 2, amount: 5000,  status: 'PENDING' },
    { id: 3, amount: 20000, status: 'PAID' }
];

const result = orders
    .filter(o => o.status === 'PAID')   // ① 결제완료만 → [주문1, 주문3]
    .map(o => o.amount)                 // ② 금액만 추출 → [10000, 20000]
    .reduce((acc, a) => acc + a, 0);    // ③ 합계 → 30000

console.log(result);   // 30000

filter → map → reduce 패턴은 SQL 의 WHERE → SELECT → SUM 과 같습니다. 의도가 직선적 으로 읽힙니다.

자주 쓰는 추가 메서드

javascript
// 정렬 (원본 변경 주의)
[3, 1, 2].sort((a, b) => a - b);   // [1, 2, 3]

// 뒤집기 (원본 변경)
[1, 2, 3].reverse();   // [3, 2, 1]

// 포함 확인
[1, 2, 3].includes(2);   // true

// 인덱스 찾기
[1, 2, 3].indexOf(2);    // 1

// 평탄화
[[1, 2], [3, 4]].flat();   // [1, 2, 3, 4]

// 합치기
const merged = [...arr1, ...arr2];   // spread

흔한 함정

1. 원본 변경 vs 새 배열:

  • sort·reverse·push·pop·splice원본 변경 ⚠️
  • map·filter·slice·concat새 배열 리턴
javascript
const arr = [3, 1, 2];
const sorted = [...arr].sort();   // 원본 보호

2. forEach vs map:

javascript
arr.forEach(x => console.log(x));   // void, 부작용만
arr.map(x => console.log(x));        // [undefined, undefined, ...]

forEach 는 부작용만, map 은 새 배열 만듭니다. 의도에 맞게.

한 번 정리

  • map·filter·reduce = 함수형 3총사
  • 체이닝으로 조립
  • 원본 변경 vs 새 배열 구분 필수
  • for 루프 거의 볼 일 없음

find · some · every · flatMap — 추가 5종

find — 처음 만나는 한 개

javascript
const users = [
    { id: 1, name: 'A' },
    { id: 2, name: 'B' }
];
const u = users.find(x => x.id === 2);
// { id: 2, name: 'B' }

const missing = users.find(x => x.id === 999);
// undefined

filter 와 달리 첫 매치에서 즉시 종료. 단건 조회의 표준.

findIndex — 위치 인덱스만

javascript
const idx = users.findIndex(x => x.name === 'B');   // 1
const missing = users.findIndex(x => false);         // -1

some / every — boolean 반환

javascript
const nums = [1, 2, 3, 4];
nums.some(n => n > 3);     // true (3 초과인 게 *하나라도* 있나)
nums.every(n => n > 0);    // true (*모두* 양수인가)

입력 검증·권한 검사 에 자주:

javascript
if (!users.every(u => u.email)) {
    throw new Error('이메일 누락된 사용자가 있음');
}

flat / flatMap — 중첩 평탄화

javascript
[1, [2, 3], [4, [5]]].flat();      // [1, 2, 3, 4, [5]]
[1, [2, 3], [4, [5]]].flat(2);     // [1, 2, 3, 4, 5]

// flatMap = map + flat(1)
const sentences = ['Hello world', 'Bye now'];
sentences.flatMap(s => s.split(' '));
// ['Hello', 'world', 'Bye', 'now']

Array.from — 유사 배열·반복가능 → 배열

javascript
Array.from('abc');             // ['a','b','c']
Array.from({ length: 5 }, (_, i) => i * 2);
// [0, 2, 4, 6, 8]

const nodeList = document.querySelectorAll('div');
Array.from(nodeList).filter(...);   // NodeList 를 배열로

체이닝 패턴 — *바이브 코딩의 단골 표현*

한 번에 변환·필터·집계

javascript
const orders = [
    { id: 1, amount: 10000, status: 'paid' },
    { id: 2, amount: 5000,  status: 'pending' },
    { id: 3, amount: 20000, status: 'paid' },
    { id: 4, amount: 3000,  status: 'cancelled' }
];

// 결제 완료된 주문의 총액
const total = orders
    .filter(o => o.status === 'paid')
    .map(o => o.amount)
    .reduce((sum, x) => sum + x, 0);
// 30000

for 루프 10줄 → 4줄 체인. AI 가 생성하는 코드의 거의 표준 패턴.

정렬 후 상위 N개

javascript
const top3 = users
    .filter(u => u.active)
    .sort((a, b) => b.score - a.score)
    .slice(0, 3);

주의: sort()원본 배열을 수정 합니다. 불변이 필요하면 [...users].sort(...) 또는 users.toSorted(...) (ES2023).

그룹화 + 변환

javascript
const byStatus = orders.reduce((acc, o) => {
    (acc[o.status] ??= []).push(o);
    return acc;
}, {});
// { paid: [...], pending: [...], cancelled: [...] }

ES2024 에선 Object.groupBy(orders, o => o.status) 한 줄로 끝.

자주 만나는 함정

1. reduce 의 초깃값 빼먹기

javascript
[].reduce((a, b) => a + b);   // ❌ TypeError
[].reduce((a, b) => a + b, 0); // ✅ 0

빈 배열에 초깃값 없으면 에러. 항상 초깃값 명시.

2. map 안에서 부수효과 만들기

javascript
// ❌ map 으로 console.log 하려고
users.map(u => console.log(u));

// ✅ forEach 또는 for...of
users.forEach(u => console.log(u));

map 은 새 배열을 만드는 목적. 결과를 안 쓰면 forEach 가 맞습니다.

🤖 AI 에게 이렇게 요청해보세요

  • "이 for 루프를 filter/map/reduce 체인으로 바꿔줘"
  • "이 코드에서 orders 중 status='paid' 인 것만 amount 합산해서 출력해줘"
  • "이 sort 호출이 원본을 변경하지 않게 toSorted 로 바꿔줘"

⚡ 직접 해보기 — map · filter · reduce 체이닝

핵심 5개 메서드 + 체이닝까지 한 번에 실행.
✏️ JS 코드
📟 콘솔 출력
▶ 실행 버튼을 눌러보세요
⚠️ 브라우저 샌드박스에서 실행 — console.log()만 지원, alert/fetch 불가
배열 고차 함수 - JavaScript