자바스크립트 - 배열 메서드로 데이터 다루기

hogu__giriboy·2026년 3월 5일

스프린트

목록 보기
6/10

원래 막 맨 앞에 내 일상을 공유하곤 했는데 ...

그럴 여유 없다 너무 어렵다 자바스크립트 ...


1. 배열 메서드

배열 메서드 중
forEach, map, filter, find 같은 순회 메서드들은
대부분 같은 형태를 가지고 있다.

array.method(function (element, index, array) {
  // 실행할 코드
});

여기서 중요한 건 콜백 함수다.

배열 메서드는 내부적으로 배열을 순회하면서
각 요소를 콜백 함수에 전달한다.

즉 구조는 항상 아래와 같은 흐름이다.

배열 순회 → 요소 전달 → 콜백 함수 실행 → 결과 생성 (메서드마다 다름)

예를 들어

const numbers = [1, 2, 3];

numbers.forEach((num) => {
  console.log(num);
});

실제로는 내부에서 이런 느낌이다.

for (let i = 0; i < numbers.length; i++) {
  callback(numbers[i], i, numbers);
}

그래서 배열 메서드는 결국

반복문을 함수 형태로 감싼 것

이라고 이해하면 된다.

배열 메서드의 4가지 목적

배열 메서드는 사실 목적이 몇 가지로 정리된다.

  1. 실행(순회) - forEach

배열을 순회하며 코드 실행

  1. 변환 - map

값을 가공해서 새 배열 생성

  1. 필터링 - filter

조건에 맞는 것만 새 배열 생성

  1. 탐색 - find/findIndex

조건에 맞는 첫 번째 값 찾기
(find는 값, findIndex는 위치를 반환)


2. 배열을 순회하는 메서드 - forEach

forEach는 배열의 각 요소를 하나씩 순회하면서
콜백 함수를 실행하는 메서드다.

기본 구조는 다음과 같다.

array.forEach(function (element, index, array) {
  // 실행할 코드
});

여기서 전달되는 값은 세 가지다.

  • element → 현재 요소
  • index → 현재 요소의 인덱스
  • array → 원본 배열

예를 들어

const numbers = [1, 2, 3];

numbers.forEach((num) => {
  console.log(num);
});

실행 결과

1
2
3

배열의 각 요소가 순서대로 전달되며
콜백 함수가 요소 개수만큼 실행된다.

for문과의 차이

forEach는 배열을 순회한다는 점에서 for문과 비슷하지만,
반복 제어(break, continue)는 사용할 수 없다.

const numbers = [1, 2, 3];

for (let i = 0; i < numbers.length; i++) {
  console.log(numbers[i]);
}

같은 동작을 forEach로 작성하면

numbers.forEach((num) => {
  console.log(num);
});

차이는 코드의 목적이 더 명확해진다는 점이다.

forEach는 이 배열을 순회하겠다라는 의도가 바로 드러난다.

중요한 특징

forEach값을 반환하지 않는다.

const numbers = [1, 2, 3];

const result = numbers.forEach((num) => num * 2);

console.log(result);

출력 결과는 undefined가 나온다.
forEach는 콜백 함수의 반환값을 사용하지 않는 메서드이기 때문에
항상 undefined를 반환한다.

forEach의 목적은 새 데이터를 만드는 것이 아니라
코드를 실행하는 것이다.
그래서 로그 출력, DOM 조작, 이벤트 등록과 같은
부수 효과(side effect) 작업에 사용된다.

반대로 새로운 배열을 만들고 싶다면 map을 사용한다.


3. 데이터를 변환하는 메서드 - map

map은 배열의 각 요소를 순회하면서
값을 변환해 새로운 배열을 만드는 메서드다.

기본 구조는 다음과 같다.

const newArray = array.map(function (element, index, array) {
  return 변환된값;
});

여기서 가장 중요한 것은 return 값이다.

map은 콜백 함수에서 반환된 값을 모아
새로운 배열을 만든다.

기본 사용

const numbers = [1, 2, 3];

const doubled = numbers.map((num) => {
  return num * 2;
});

console.log(doubled);

실행 결과는 [2, 4, 6]으로
원본 배열은 변하지 않으므로 [1, 2, 3]이다.

map의 핵심 특징

map의 목적은 데이터 변환이다.

예를 들어

const users = [
  { name: "홍길동", age: 25 },
  { name: "김철수", age: 30 },
];

이 배열에서 이름만 추출하고 싶다면

const names = users.map((user) => user.name);

console.log(names);

출력 결과는 ["홍길동", "김철수"]가 된다.

이처럼 map은 기존 데이터를 다른 형태의 데이터로 변환할 때 사용한다.

forEach와의 차이

초보자가 가장 많이 헷갈리는 부분이다.

forEach

numbers.forEach((num) => {
  console.log(num);
});
  • 반환값 없음
  • 코드 실행 목적

map

const doubled = numbers.map((num) => num * 2);
  • 새 배열 생성
  • 데이터 변환 목적

핵심 차이는 이것이다.
forEach는 코드를 실행하기 위한 메서드이고
map은 데이터를 변환해 새로운 배열을 만들기 위한 메서드다.


4. 조건에 맞는 데이터를 걸러내는 메서드 - filter

filter는 배열을 순회하면서
조건에 맞는 요소만 남겨 새로운 배열을 만드는 메서드다.

기본 구조는 다음과 같다.

const newArray = array.filter(function (element, index, array) {
  return 조건;
});

콜백 함수가 true를 반환하면 해당 요소가 배열에 포함되고,
false를 반환하면 제외된다.

기본 사용

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

const evens = numbers.filter((num) => num % 2 === 0);

console.log(evens);

실행 결과는 [2, 4, 6]으로
filter 역시 map과 마찬가지로
원본 배열을 변경하지 않고 새로운 배열을 만든다.

객체 배열에서 활용

실무에서는 보통 객체 배열을 조건으로 걸러낼 때 많이 사용한다.

const users = [
  { name: "홍길동", age: 25 },
  { name: "김철수", age: 30 },
  { name: "이영희", age: 22 },
];

예를 들어 25세 이상 사용자만 찾는다면

const adults = users.filter((user) => user.age >= 25);

console.log(adults);

출력 결과

[
  { name: "홍길동", age: 25 },
  { name: "김철수", age: 30 }
]

이처럼 filter조건에 맞는 데이터만 선택하는 역할을 한다.

map과 함께 사용하는 패턴

실제 코드에서는 filtermap을 함께 사용하는 경우가 많다.

예를 들어 25세 이상 사용자의 이름만 추출하려면

const names = users.filter((user) => user.age >= 25).map((user) => user.name);

console.log(names);

출력 결과는 ["홍길동", "김철수"]
이 패턴은 filter데이터를 먼저 걸러낸 뒤
map으로 필요한 형태로 변환하는 방식이다.

filter와 find의 차이

여기서 하나 더 알아두면 좋은 것이 find다.
바로 다음에 다루긴 하겠지만, 잠깐 간단하게 비교하면

우선 둘 다 조건을 사용하지만 결과가 다르다.

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

const filtered = numbers.filter((n) => n > 3);
const found = numbers.find((n) => n > 3);

filtered의 결과는 [4, 5, 6],
found의 결과는 4

filter는 조건에 맞는 모든 요소를 배열로 반환하고,
find는 조건에 맞는 첫 번째 요소 하나를 반환한다.


5. 특정 데이터를 찾는 메서드 - find / findIndex

findfindIndex는 배열을 순회하면서
조건에 맞는 요소를 찾는 메서드다.

두 메서드는 구조가 동일하지만 반환값이 다르다.

기본 구조는 다음과 같다.

array.find(function (element, index, array) {
  return 조건;
});

array.findIndex(function (element, index, array) {
  return 조건;
});

find - 요소 찾기

find는 조건에 맞는 첫 번째 요소를 반환한다.

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

const found = numbers.find((num) => num > 3);

console.log(found);

출력 결과는 4다.

조건을 만족하는 값이 여러 개 있어도
가장 먼저 발견된 요소 하나만 반환한다.

만약 조건에 맞는 값이 없다면 undefined가 반환된다.

const result = numbers.find((num) => num > 10);

console.log(result);

출력 결과는 undefined다.

findIndex - 위치 찾기

findIndex는 조건에 맞는 요소의 인덱스를 반환한다.

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

const index = numbers.findIndex((num) => num > 3);

console.log(index);

출력 결과는 3이다.

배열 [1, 2, 3, 4, 5]에서
4의 인덱스가 3이기 때문이다.

조건에 맞는 요소가 없으면 -1이 반환된다.

const result = numbers.findIndex((num) => num > 10);

console.log(result);

출력 결과는 -1이다.

filter와의 차이

앞에서도 filter와 비교했었는데, 다시 한 번 비교해보자면
filter는 조건에 맞는 모든 요소를 배열로 반환하고,
find는 조건에 맞는 첫 번째 요소를 반환하며,
findIndex는 조건에 맞는 요소의 위치를 반환한다.

정리하면 다음과 같다.

  • 여러 개가 필요하면 filter
  • 하나만 필요하면 find
  • 위치가 필요하면 findIndex

6. 조건을 검사하는 메서드 - some / every

someevery는 배열을 순회하면서
조건을 검사하는 메서드다.

두 메서드는 구조는 비슷하지만
조건을 판단하는 기준이 다르다.

기본 구조는 다음과 같다.

array.some(function (element, index, array) {
  return 조건;
});

array.every(function (element, index, array) {
  return 조건;
});

some - 하나라도 만족하면 true

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

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

const result = numbers.some((num) => num > 3);

console.log(result);

출력 결과는 true다.

왜냐하면 배열 안에 3보다 큰 값이 존재하기 때문이다.

반대로 조건을 만족하는 값이 하나도 없다면 false가 된다.

const result = numbers.some((num) => num > 10);

console.log(result);

출력 결과는 false다.

every - 모두 만족해야 true

every는 배열의 모든 요소가 조건을 만족해야 true를 반환한다.

const numbers = [2, 4, 6, 8];

const result = numbers.every((num) => num % 2 === 0);

console.log(result);

출력 결과는 true다.

모든 값이 짝수이기 때문이다.

하지만 하나라도 조건을 만족하지 못하면 false가 된다.

const numbers = [2, 4, 5, 8];

const result = numbers.every((num) => num % 2 === 0);

console.log(result);

출력 결과는 false다.

some과 every의 차이

some은 조건을 만족하는 요소가 하나라도 있는가,
every는 모든 요소가 조건을 만족하는가를 본다.

쉽게 생각하면

  • someOR 조건 검사
  • everyAND 조건 검사

라고 이해할 수 있다.

반대로 두 메서드 모두 조건이 확정되는 순간 순회를 멈춘다는 공통점도 있다.


7. 배열을 정렬하는 메서드 - sort / reverse

sortreverse는 배열의 순서를 바꾸는 메서드다.

앞에서 다룬 map, filter와 다르게
이 메서드들은 원본 배열을 직접 변경한다.

sort - 배열 정렬

sort는 배열의 요소를 정렬하는 메서드다.

가장 기본적인 사용은 다음과 같다.

const fruits = ["banana", "apple", "cherry"];

fruits.sort();

console.log(fruits);

출력 결과는 ["apple", "banana", "cherry"],
문자열 배열에서는 사전 순으로 정렬된다.

숫자 정렬 시 주의점

sort는 기본적으로 문자열 기준으로 정렬되기 때문에
숫자를 정렬할 때는 비교 함수를 전달해야 한다.

숫자 배열을 그대로 sort()하면
의도와 다른 결과가 나올 수 있다.

const numbers = [10, 5, 40, 25];

numbers.sort((a, b) => a - b);

console.log(numbers);

출력 결과는 [5, 10, 25, 40],

여기서 a - b의 의미는 다음과 같다.

  • a - b < 0 → a가 앞
  • a - b > 0 → b가 앞
  • a - b = 0 → 순서 유지

오름차순 정렬이 된다.

반대로 내림차순은 다음과 같이 작성할 수 있다.

numbers.sort((a, b) => b - a);

reverse - 배열 뒤집기

reverse는 배열의 순서를 반대로 뒤집는 메서드다.

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

numbers.reverse();

console.log(numbers);

출력 결과는 [4, 3, 2, 1]
reverse 역시 원본 배열을 변경한다.

원본 배열 보존하기

sort는 원본 배열을 변경하기 때문에
원본을 유지하려면 배열을 복사한 뒤 정렬해야 한다.

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

const sorted = [...numbers].sort((a, b) => a - b);

console.log(numbers); // [3, 1, 4, 2]
console.log(sorted); // [1, 2, 3, 4]

이처럼 스프레드 문법(...)을 사용해 배열을 복사할 수 있다.


8. 배열을 하나의 값으로 만드는 메서드 - reduce

reduce는 배열을 순회하면서
여러 값을 하나의 값으로 축약하는 메서드다.

기본 구조는 다음과 같다.

array.reduce(function (acc, element, index, array) {
  return 새로운누적값;
}, 초기값);

여기서 중요한 값은 누적값(accumulator)이다.

reduce는 각 요소를 순회하면서
이전 계산 결과를 다음 계산에 계속 누적한다.

기본 사용 - 합계 구하기

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

const sum = numbers.reduce((acc, num) => {
  return acc + num;
}, 0);

console.log(sum);

출력 결과는 15다.

동작 흐름은 다음과 같다.

acc = 0, num = 1 → 1
acc = 1, num = 2 → 3
acc = 3, num = 3 → 6
acc = 6, num = 4 → 10
acc = 10, num = 5 → 15

이처럼 reduce는 값을 계속 누적하면서 하나의 결과를 만들어낸다.

reduce가 어려운 이유

reduce는 다른 배열 메서드와 달리
결과 형태가 정해져 있지 않다.

예를 들어

  • 숫자 합계 계산
  • 배열을 하나로 합치기
  • 객체 생성
  • 데이터 그룹화

등 다양한 방식으로 사용할 수 있다.

그래서 처음에는 map, filter보다
동작 흐름을 이해하기 어렵게 느껴질 수 있다.

실제로 많은 경우에는

  • 데이터 변환map
  • 데이터 필터filter

를 사용하는 것이 더 직관적이다.

reduce를 사용하는 순간

reduce는 보통 다음과 같은 상황에서 사용한다.

  • 합계 계산
  • 통계 계산
  • 데이터 그룹화
  • 하나의 결과값 생성

즉 배열 데이터를 하나의 결과로 집계하거나 요약할 때 사용한다.


9. 핵심 정리

배열 메서드는 대부분 배열을 순회하면서 콜백 함수를 실행하는 구조를 가진다.

배열 순회 → 요소 전달 → 콜백 실행 → 결과 반환

각 메서드는 같은 구조 위에서 목적만 다르게 동작한다.

배열 메서드의 역할 정리

메서드목적
forEach배열을 순회하며 코드 실행
map데이터를 변환하여 새 배열 생성
filter조건에 맞는 요소만 남겨 새 배열 생성
find조건에 맞는 첫 번째 요소 반환
findIndex조건에 맞는 요소의 인덱스 반환
some조건을 만족하는 요소가 하나라도 있는지 검사
every모든 요소가 조건을 만족하는지 검사
sort배열 정렬 (원본 변경)
reverse배열 순서 뒤집기 (원본 변경)
reduce배열을 하나의 값으로 누적 / 축약

배열 메서드를 사용할 때 기억할 것

배열 메서드는 목적에 맞게 선택하는 것이 중요하다.

예를 들어

  • 데이터를 변환하려면 map
  • 조건에 맞는 데이터만 고르려면 filter
  • 하나의 값만 찾으려면 find

이처럼 문제의 목적에 맞는 메서드를 선택하면 코드가 훨씬 읽기 쉬워진다.

결국 배열 메서드는 반복문을 더 의도적으로 표현하는 도구다.

0개의 댓글