우당탕탕 FE 개발자 이야기

[JavaScript] 배열 메서드 완벽 정리 (Array Method) 2탄 - 탐색/검색 본문

개발

[JavaScript] 배열 메서드 완벽 정리 (Array Method) 2탄 - 탐색/검색

우당탕탕 FE 2025. 12. 3. 16:19

 

1탄에서는 배열에 요소를 추가하고 제거하는 방법을 알아봤습니다. 이번 2탄에서는 배열에서 원하는 요소를 찾는 다양한 탐색/검색 메서드들을 정리해보겠습니다.

1. find() - 조건에 맞는 첫 번째 요소 찾기

find()는 주어진 조건을 만족하는 첫 번째 요소를 반환합니다. 조건에 맞는 요소가 없으면 undefined를 반환합니다.

 

문법:

array.find(callback(element, index, array))

 

기본 예시:

const numbers = [5, 12, 8, 130, 44];

// 10보다 큰 첫 번째 숫자 찾기
const found = numbers.find(num => num > 10);

console.log(found); // 12

 

실무 활용 예시:

// 사용자 목록에서 특정 ID로 사용자 찾기
const users = [
  { id: 1, name: '김철수', age: 25 },
  { id: 2, name: '이영희', age: 30 },
  { id: 3, name: '박민수', age: 28 }
];

const user = users.find(user => user.id === 2);
console.log(user); // { id: 2, name: '이영희', age: 30 }

// 30세 이상인 첫 번째 사용자 찾기
const adultUser = users.find(user => user.age >= 30);
console.log(adultUser); // { id: 2, name: '이영희', age: 30 }

// 조건에 맞는 사용자가 없는 경우
const youngUser = users.find(user => user.age < 20);
console.log(youngUser); // undefined

 

주의사항:

  • 조건을 만족하는 첫 번째 요소만 반환합니다
  • 모든 요소를 찾고 싶다면 filter()를 사용하세요 (3탄에서 다룰 예정!)

2. findIndex() - 조건에 맞는 첫 번째 인덱스 찾기

findIndex()는 주어진 조건을 만족하는 첫 번째 요소의 인덱스를 반환합니다. 조건에 맞는 요소가 없으면 -1을 반환합니다.

 

문법:

array.findIndex(callback(element, index, array))

 

기본 예시:

const numbers = [5, 12, 8, 130, 44];

// 10보다 큰 첫 번째 숫자의 인덱스
const index = numbers.findIndex(num => num > 10);

console.log(index); // 1 (numbers[1] = 12)

 

실무 활용 예시:

// 장바구니에서 특정 상품의 위치 찾기
const cart = [
  { id: 1, name: '노트북', quantity: 1 },
  { id: 2, name: '마우스', quantity: 2 },
  { id: 3, name: '키보드', quantity: 1 }
];

const mouseIndex = cart.findIndex(item => item.name === '마우스');
console.log(mouseIndex); // 1

// 해당 인덱스를 이용해서 수량 업데이트
if (mouseIndex !== -1) {
  cart[mouseIndex].quantity += 1;
  console.log(cart[mouseIndex]); // { id: 2, name: '마우스', quantity: 3 }
}

// 상품 삭제에도 활용 가능
const keyboardIndex = cart.findIndex(item => item.name === '키보드');
if (keyboardIndex !== -1) {
  cart.splice(keyboardIndex, 1);
}
console.log(cart); // 키보드가 제거된 배열

 

find() vs findIndex() 언제 사용할까?

  • 요소 자체가 필요하면 → find()
  • 위치(인덱스)가 필요하면 → findIndex()
  • 인덱스를 알면 배열을 수정하거나 요소를 제거할 수 있어요!

3. indexOf() - 특정 값의 인덱스 찾기

indexOf()는 배열에서 지정된 요소를 찾아 첫 번째 인덱스를 반환합니다. 요소가 없으면 -1을 반환합니다.

 

문법:

array.indexOf(searchElement, fromIndex)
  • searchElement: 찾을 요소
  • fromIndex: 검색을 시작할 인덱스 (선택사항, 기본값 0)

기본 예시:

const fruits = ['사과', '바나나', '오렌지', '바나나'];

console.log(fruits.indexOf('바나나')); // 1 (첫 번째 바나나)
console.log(fruits.indexOf('포도')); // -1 (없음)

// 두 번째 파라미터: 검색 시작 위치
console.log(fruits.indexOf('바나나', 2)); // 3 (인덱스 2부터 찾기 시작)

 

실무 활용 예시:

// 중복 체크
const selectedItems = ['item1', 'item2', 'item3'];
const newItem = 'item2';

if (selectedItems.indexOf(newItem) === -1) {
  selectedItems.push(newItem);
  console.log('아이템이 추가되었습니다');
} else {
  console.log('이미 선택된 아이템입니다');
}

// 태그 토글 기능
const tags = ['JavaScript', 'React', 'Node.js'];
const tagToToggle = 'React';

const tagIndex = tags.indexOf(tagToToggle);
if (tagIndex === -1) {
  tags.push(tagToToggle); // 없으면 추가
} else {
  tags.splice(tagIndex, 1); // 있으면 제거
}
console.log(tags); // ['JavaScript', 'Node.js']

 

주의사항:

  • === 엄격한 동등 비교를 사용합니다
  • 객체나 배열을 찾을 때는 참조를 비교합니다
 
const arr = [{ id: 1 }, { id: 2 }];
console.log(arr.indexOf({ id: 1 })); // -1 (다른 객체이므로)

const obj = { id: 1 };
const arr2 = [obj, { id: 2 }];
console.log(arr2.indexOf(obj)); // 0 (같은 참조)

4. lastIndexOf() - 뒤에서부터 인덱스 찾기

lastIndexOf()는 배열을 뒤에서부터 검색하여 지정된 요소의 마지막 인덱스를 반환합니다.

 

기본 예시:

const numbers = [2, 5, 9, 2, 7, 2];

console.log(numbers.indexOf(2)); // 0 (첫 번째 2)
console.log(numbers.lastIndexOf(2)); // 5 (마지막 2)
console.log(numbers.lastIndexOf(8)); // -1 (없음)

 

실무 활용 예시:

// 파일 확장자 추출
const fileName = 'document.backup.pdf';
const lastDotIndex = fileName.lastIndexOf('.');

if (lastDotIndex !== -1) {
  const extension = fileName.substring(lastDotIndex + 1);
  console.log(extension); // 'pdf'
}

5. includes() - 특정 값 포함 여부 확인

includes()는 배열에 특정 요소가 포함되어 있는지 true/false로 반환합니다.

 

문법:

array.includes(searchElement, fromIndex)

 

기본 예시:

const fruits = ['사과', '바나나', '오렌지'];

console.log(fruits.includes('바나나')); // true
console.log(fruits.includes('포도')); // false

// NaN도 찾을 수 있습니다 (indexOf는 불가능)
const numbers = [1, 2, NaN, 4];
console.log(numbers.includes(NaN)); // true
console.log(numbers.indexOf(NaN)); // -1

 

실무 활용 예시:

// 권한 체크
const userRoles = ['user', 'editor', 'viewer'];

if (userRoles.includes('admin')) {
  console.log('관리자 권한이 있습니다');
} else {
  console.log('관리자 권한이 없습니다');
}

// 허용된 파일 확장자 체크
const allowedExtensions = ['jpg', 'png', 'gif', 'webp'];
const uploadedFile = 'image.jpg';
const fileExtension = uploadedFile.split('.').pop();

if (allowedExtensions.includes(fileExtension)) {
  console.log('업로드 가능한 파일입니다');
} else {
  console.log('지원하지 않는 파일 형식입니다');
}

// 필수 항목 체크
const requiredFields = ['name', 'email', 'password'];
const submittedFields = ['name', 'email'];

const missingFields = requiredFields.filter(field => 
  !submittedFields.includes(field)
);
console.log('누락된 항목:', missingFields); // ['password']

 

indexOf() vs includes()

// indexOf: 인덱스가 필요할 때
if (array.indexOf(item) !== -1) { /* 있음 */ }

// includes: 존재 여부만 확인할 때 (더 읽기 쉬움)
if (array.includes(item)) { /* 있음 */ }

6. some() - 하나라도 조건을 만족하는가?

some()은 배열의 하나라도 조건을 만족하면 true를 반환합니다.

 

문법:

array.some(callback(element, index, array))

 

기본 예시:

const numbers = [1, 3, 5, 7, 10];

// 짝수가 하나라도 있는가?
const hasEven = numbers.some(num => num % 2 === 0);
console.log(hasEven); // true (10이 짝수)

// 20보다 큰 수가 있는가?
const hasLarge = numbers.some(num => num > 20);
console.log(hasLarge); // false

 

실무 활용 예시:

// 폼 검증: 빈 필드가 하나라도 있는지 체크
const formData = {
  username: 'john',
  email: '',
  password: 'secret123'
};

const hasEmptyField = Object.values(formData).some(value => value === '');
if (hasEmptyField) {
  console.log('모든 필드를 입력해주세요');
}

// 장바구니에 할인 상품이 있는지 체크
const cartItems = [
  { name: '노트북', price: 1000000, discount: false },
  { name: '마우스', price: 30000, discount: true },
  { name: '키보드', price: 80000, discount: false }
];

const hasDiscountItem = cartItems.some(item => item.discount);
if (hasDiscountItem) {
  console.log('할인 혜택을 받을 수 있습니다!');
}

// 성인 사용자가 있는지 체크
const users = [
  { name: '김철수', age: 17 },
  { name: '이영희', age: 25 },
  { name: '박민수', age: 16 }
];

const hasAdult = users.some(user => user.age >= 18);
console.log('성인 사용자 포함:', hasAdult); // true

7. every() - 모두 조건을 만족하는가?

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

 

문법:

array.every(callback(element, index, array))

 

기본 예시:

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

// 모두 짝수인가?
const allEven = numbers.every(num => num % 2 === 0);
console.log(allEven); // true

// 모두 5보다 큰가?
const allLarge = numbers.every(num => num > 5);
console.log(allLarge); // false (2, 4가 5 이하)

 

실무 활용 예시:

// 모든 필수 항목이 입력되었는지 체크
const formFields = [
  { name: 'username', value: 'john', required: true },
  { name: 'email', value: 'john@example.com', required: true },
  { name: 'phone', value: '', required: false }
];

const allRequiredFilled = formFields
  .filter(field => field.required)
  .every(field => field.value !== '');

if (allRequiredFilled) {
  console.log('폼 제출 가능');
} else {
  console.log('필수 항목을 모두 입력해주세요');
}

// 모든 상품이 재고가 있는지 체크
const products = [
  { name: '노트북', stock: 5 },
  { name: '마우스', stock: 10 },
  { name: '키보드', stock: 3 }
];

const allInStock = products.every(product => product.stock > 0);
if (allInStock) {
  console.log('모든 상품 구매 가능');
}

// 모든 사용자가 성인인지 체크
const groupMembers = [
  { name: '김철수', age: 25 },
  { name: '이영희', age: 30 },
  { name: '박민수', age: 28 }
];

const allAdults = groupMembers.every(member => member.age >= 18);
console.log('성인 그룹:', allAdults); // true

 

some() vs every()

const scores = [85, 90, 75, 88];

// 하나라도 90점 이상인가?
console.log(scores.some(score => score >= 90)); // true

// 모두 80점 이상인가?
console.log(scores.every(score => score >= 80)); // false (75점이 있음)

// 모두 60점 이상인가?
console.log(scores.every(score => score >= 60)); // true

메서드 비교표

 

메서드 반환값 조건 기반 객체 검색 용도
find() 요소 또는 undefined 조건에 맞는 요소 찾기
findIndex() 인덱스 또는 -1 조건에 맞는 인덱스 찾기
indexOf() 인덱스 또는 -1 ⚠️ (참조 비교) 특정 값의 인덱스 찾기
lastIndexOf() 인덱스 또는 -1 ⚠️ (참조 비교) 뒤에서부터 인덱스 찾기
includes() true/false ⚠️ (참조 비교) 존재 여부 확인
some() true/false 하나라도 만족하는지 확인
every() true/false 모두 만족하는지 확인

실전 종합 예제

다양한 검색 메서드를 함께 사용하는 실무 예제입니다.

// 쇼핑몰 상품 관리 시스템
const products = [
  { id: 1, name: '노트북', price: 1200000, stock: 5, category: 'electronics' },
  { id: 2, name: '마우스', price: 30000, stock: 0, category: 'electronics' },
  { id: 3, name: '책상', price: 150000, stock: 3, category: 'furniture' },
  { id: 4, name: '의자', price: 80000, stock: 7, category: 'furniture' }
];

// 1. 특정 ID의 상품 찾기
const productId = 3;
const product = products.find(p => p.id === productId);
console.log('찾은 상품:', product);

// 2. 재고가 없는 상품이 있는지 확인
const hasOutOfStock = products.some(p => p.stock === 0);
console.log('품절 상품 있음:', hasOutOfStock);

// 3. 모든 상품이 특정 카테고리에 속하는지 확인
const allElectronics = products.every(p => p.category === 'electronics');
console.log('모두 전자제품:', allElectronics);

// 4. 특정 카테고리가 포함되어 있는지 확인
const categories = products.map(p => p.category);
const hasFurniture = categories.includes('furniture');
console.log('가구 카테고리 있음:', hasFurniture);

// 5. 가격이 50만원 이하인 상품의 인덱스 찾기
const affordableIndex = products.findIndex(p => p.price <= 500000);
console.log('저렴한 상품의 인덱스:', affordableIndex);

// 6. 재고가 있고 10만원 이하인 상품 찾기
const budgetProduct = products.find(p => 
  p.stock > 0 && p.price <= 100000
);
console.log('예산 내 구매 가능 상품:', budgetProduct);

성능 팁

  1. 조기 종료 활용
    • find(), some(), every()는 조건을 만족하면 즉시 중단됩니다
    • 대용량 배열에서 효율적입니다
  2. 적절한 메서드 선택
    • 존재 여부만 확인: includes() (가장 간단)
    • 복잡한 조건: find(), some(), every()
    • 간단한 값 찾기: indexOf()
  3. 불필요한 반복 피하기
 
// ❌ 비효율적
const hasItem = array.filter(item => item.id === targetId).length > 0;

// ✅ 효율적
const hasItem = array.some(item => item.id === targetId);

마무리

배열에서 원하는 요소를 찾는 7가지 메서드를 알아봤습니다!

 

간단 정리:

  • 요소 찾기: find(), indexOf(), includes()
  • 인덱스 찾기: findIndex(), indexOf(), lastIndexOf()
  • 조건 확인: some() (하나라도), every() (모두)

다음 3탄에서는 배열을 변환하는 강력한 메서드들(map(), filter(), reduce() 등)을 다뤄보겠습니다!


관련 포스트: