14. 고급 배열 마법사 (고급 배열 메서드)/14.4 배열 검색과 정렬

14.4.1 `find`, `findIndex` - 배열에서 원하는 친구를 찾아주는 똑똑한 도우미들

thejavascript4kids 2025. 7. 21. 03:25

📘 14.4.1 find, findIndex - 배열에서 원하는 친구를 찾아주는 똑똑한 도우미들

안녕하세요, 여러분. 오늘은 참 소중한 두 명의 도우미를 만나볼 거예요. 우리가 책상 서랍에서 필요한 물건을 찾을 때처럼, 긴 목록에서 딱 원하는 것만 쏙 찾아주는 고마운 친구들이 있거든요. 바로 findfindIndex라는 이름을 가진 도우미들입니다.

여러분도 교실에서 "키가 큰 친구가 누구지?" 하고 둘러본 적이 있죠? 앞자리부터 한 명씩 확인하다가 키 큰 친구를 발견하면 "아, 저기 있네!" 하며 찾는 걸 멈추잖아요. 이 도우미들도 그런 방식으로 일을 해요.

🧠 새로운 단어들과 친해지기

배열에서 검색할 때 자주 사용하는 중요한 단어들을 차근차근 알아볼게요.

단어 쉬운 설명
find 조건에 맞는 첫 번째 것을 찾아서 그것 자체를 가져다주는 도우미예요.
findIndex 조건에 맞는 첫 번째 것의 위치(몇 번째인지)를 알려주는 도우미예요.
조건 함수 find나 findIndex에게 "이런 것을 찾아줘"라고 설명하는 함수예요.
첫 번째 발견 조건에 맞는 것이 여러 개 있어도 가장 앞의 것만 찾는다는 뜻이에요.

find는 "찾다"라는 뜻의 영어 단어이고, findIndex는 "순서를 찾다"라는 의미예요.

findfindIndex가 뭔지 알아보기

findfindIndex는 배열에서 우리가 원하는 특별한 조건을 만족하는 것을 찾는 데 쓰이는 도우미들이에요. 이 둘의 가장 중요한 특징은 첫 번째로 조건에 맞는 것만 찾으면 바로 멈춘다는 거예요.

find는 찾은 그것 자체를 우리에게 건네주고, findIndex는 그것이 몇 번째 자리에 있는지 알려줍니다. 만약 조건에 맞는 것이 없다면 findundefined를, findIndex-1을 알려줘요.

이 도우미들은 filter와 비슷하지만 중요한 차이가 있어요. filter는 조건에 맞는 모든 것들을 다 찾아서 새로운 배열을 만들지만, findfindIndex첫 번째 하나만 찾으면 그만두기 때문에 더 빠르고 효율적입니다.

재미있는 비유: 반에서 특별한 친구 찾기

findfindIndex를 더 쉽게 이해하기 위해서 '교실에서 특별한 친구를 찾는 상황'에 비유해볼게요.

선생님이 "안경을 쓴 친구를 찾아보세요"라고 하셨다고 생각해보세요. 여러분은 앞자리부터 차례대로 친구들을 확인하기 시작해요. 첫 번째 친구... 안경 없음, 두 번째 친구... 안경 없음, 세 번째 친구... 안경 발견!

이때 find 도우미는 "철수예요!"라고 그 친구의 정보를 알려주고, findIndex 도우미는 "3번째 자리에 앉아있어요!"라고 위치를 알려줍니다. 둘 다 첫 번째로 조건에 맞는 친구를 찾자마자 검색을 끝내요.

만약 안경을 쓴 친구가 없다면, find는 "찾을 수 없어요(undefined)", findIndex는 "어디에도 없어요(-1)"라고 대답합니다.

🎯 왜 findfindIndex를 배워야 할까요?

우리는 왜 이 검색 도우미들을 배워야 할까요?

첫 번째로, 일상생활에서 정말 자주 사용되기 때문이에요. 친구 목록에서 특정 친구 찾기, 상품 목록에서 원하는 상품 찾기 등 일상적인 검색 작업에 꼭 필요합니다.

두 번째로, 빠르고 효율적인 검색이 가능해요. 배열 전체를 다 확인할 필요 없이, 원하는 것을 찾으면 바로 멈추므로 시간을 절약할 수 있습니다.

세 번째로, 정확한 정보를 얻을 수 있어요. 그것 자체가 필요한지, 위치가 필요한지에 따라 findfindIndex 중 적절한 것을 선택할 수 있습니다.

마지막으로, 안전한 코딩을 도와줘요. 조건에 맞는 것이 없을 때의 상황도 명확하게 처리할 수 있어서 실수를 줄일 수 있습니다.

⚙️ 기본 사용법 살펴보기

findfindIndex의 기본적인 사용법을 알아보겠습니다.

// find - 그것 자체를 가져오기
let 찾은것 = 배열.find(function(각각의것) {
    return 조건식;
});

// findIndex - 그것의 위치를 가져오기
let 찾은위치 = 배열.findIndex(function(각각의것) {
    return 조건식;
});

// 더 간단하게 쓰기
let 결과 = 배열.find(각각의것 => 조건식);
let 위치 = 배열.findIndex(각각의것 => 조건식);

기본 예시:

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

// 10보다 큰 첫 번째 숫자 찾기
let bigNumber = numbers.find(function(num) {
    return num > 10;
});

// 10보다 큰 첫 번째 숫자의 위치 찾기
let bigNumberIndex = numbers.findIndex(function(num) {
    return num > 10;
});

console.log(bigNumber);      // 12
console.log(bigNumberIndex); // 1 (0부터 시작하는 위치)

🧪 직접 해보면서 배우기

이제 실제 상황에서 findfindIndex를 사용하는 예시들을 살펴보겠습니다.

🔹 첫 번째 예시: 반 친구들 중에서 특정 친구 찾기

우리 반 친구들 정보에서 특정 조건에 맞는 친구를 찾아보겠습니다.

// 우리 반 친구들 정보
let classmates = [
    { name: "김철수", age: 10, hobby: "축구" },
    { name: "이영희", age: 11, hobby: "그림" },
    { name: "박민수", age: 10, hobby: "독서" },
    { name: "정지은", age: 11, hobby: "음악" }
];

// 나이가 11살인 첫 번째 친구 찾기
let elevenYearOld = classmates.find(function(friend) {
    return friend.age === 11;
});

console.log("11살 친구:", elevenYearOld);
// { name: "이영희", age: 11, hobby: "그림" }

// 축구를 좋아하는 친구의 위치 찾기
let soccerFanIndex = classmates.findIndex(function(friend) {
    return friend.hobby === "축구";
});

console.log("축구 좋아하는 친구 위치:", soccerFanIndex); // 0

// 없는 조건으로 찾기
let swimmer = classmates.find(friend => friend.hobby === "수영");
console.log("수영 좋아하는 친구:", swimmer); // undefined

이 예시에서는 배열 안의 정보 묶음에서 특정 내용으로 검색하는 방법을 보여줍니다.

🔹 두 번째 예시: 상점에서 원하는 물건 찾기

상점의 물건들 중에서 조건에 맞는 상품을 찾아보겠습니다.

// 문구점 물건들 목록
let stationery = [
    { name: "연필", price: 500, color: "노란색" },
    { name: "지우개", price: 300, color: "흰색" },
    { name: "볼펜", price: 800, color: "파란색" },
    { name: "마커", price: 1200, color: "빨간색" }
];

// 1000원 이하인 첫 번째 물건 찾기
let cheapItem = stationery.find(function(item) {
    return item.price <= 1000;
});

console.log("1000원 이하 물건:", cheapItem.name, cheapItem.price + "원");
// "연필 500원"

// 파란색 물건의 위치 찾기
let blueItemIndex = stationery.findIndex(function(item) {
    return item.color === "파란색";
});

console.log("파란색 물건 위치:", blueItemIndex); // 2

// 검색 결과 안전하게 사용하기
let greenItem = stationery.find(item => item.color === "초록색");
if (greenItem) {
    console.log("초록색 물건:", greenItem.name);
} else {
    console.log("초록색 물건이 없어요");
}

이 예시에서는 검색 결과를 안전하게 사용하는 방법도 함께 보여줍니다.

🔹 세 번째 예시: 게임 점수에서 특별한 기록 찾기

게임 점수 목록에서 특정 조건에 맞는 점수를 찾아보겠습니다.

// 최근 게임 점수들
let gameScores = [45, 67, 82, 156, 78, 134, 92];

// 100점 이상인 첫 번째 점수 찾기
let highScore = gameScores.find(function(score) {
    return score >= 100;
});

// 100점 이상인 첫 번째 점수의 위치 찾기
let highScoreIndex = gameScores.findIndex(function(score) {
    return score >= 100;
});

// 검색하는 기능 만들기
function findScoreInfo(scores, targetScore) {
    let foundScore = scores.find(score => score >= targetScore);
    let foundIndex = scores.findIndex(score => score >= targetScore);

    if (foundScore) {
        console.log(`${targetScore}점 이상 첫 기록: ${foundScore}점`);
        console.log(`위치: ${foundIndex + 1}번째 게임`);
    } else {
        console.log(`${targetScore}점 이상인 기록이 없어요`);
    }
}

// 기능 사용해보기
findScoreInfo(gameScores, 100); // "100점 이상 첫 기록: 156점, 위치: 4번째 게임"
findScoreInfo(gameScores, 200); // "200점 이상인 기록이 없어요"

이 예시에서는 검색 기능을 함수로 만들어서 다시 사용할 수 있게 했습니다.

🔄 검색 과정 정리하기

지금까지 배운 findfindIndex의 사용 과정을 단계별로 정리해보겠습니다.

첫 번째 단계는 검색 조건 정하기입니다. 어떤 특징을 가진 것을 찾고 싶은지 명확히 결정해야 해요.

두 번째는 적절한 도우미 선택 단계입니다. 그것 자체가 필요하면 find, 위치가 필요하면 findIndex를 선택합니다.

세 번째는 조건 함수 작성 단계입니다. 각각에 대해 조건을 확인하는 함수를 작성해야 해요.

마지막으로 결과 확인 단계입니다. 찾았는지(undefined-1이 아닌지) 반드시 확인하고 적절히 처리해야 합니다.

🧠 자주 하는 실수와 주의할 점

findfindIndex를 사용할 때 자주 하는 실수들을 알아보고 피하는 방법을 살펴보겠습니다.

❌ 실수 1: 검색 결과를 확인하지 않고 사용하기

// 위험한 예시 - 결과 확인 없이 사용
let friends = [{ name: "철수" }, { name: "영희" }];

let friend = friends.find(f => f.name === "민수");
console.log(friend.name); // 에러! undefined에서 name을 찾을 수 없어요

// 안전한 방법
let safeFriend = friends.find(f => f.name === "민수");
if (safeFriend) {
    console.log("찾은 친구:", safeFriend.name);
} else {
    console.log("그런 이름의 친구가 없어요");
}

find는 못 찾으면 undefined를 돌려주므로 반드시 확인해야 해요.

❌ 실수 2: filter와 혼동하기

// 잘못된 기대 - find가 여러 개를 반환한다고 생각
let ages = [10, 12, 10, 11, 10];
let result = ages.find(age => age === 10);
console.log(result); // 10 (첫 번째 10만 반환)

// 모든 10을 찾으려면 filter 사용
let allTens = ages.filter(age => age === 10);
console.log(allTens); // [10, 10, 10]

find는 첫 번째 하나만 찾고, 모든 것을 찾으려면 filter를 써야 해요.

❌ 실수 3: 조건식에서 실수하기

// 잘못된 조건 - 할당 기호 사용
let numbers = [1, 2, 3, 4, 5];
let wrong = numbers.find(num => num = 3); // = 사용 (틀림!)

// 올바른 조건 - 비교 기호 사용
let correct = numbers.find(num => num === 3); // === 사용 (맞음!)
console.log(correct); // 3

조건에서는 비교 기호(===)를 사용해야 하고, 할당 기호(=)와 혼동하면 안 돼요.

✏️ 연습문제로 개념 다지기

여러분, 이제 실제로 코드를 만져보며 느껴볼 시간이에요. 손으로 직접 만지고 눈으로 확인하는 것만큼 확실한 배움은 없거든요. 차근차근 따라오세요.

Ex1) "고"로 시작하는 동물을 찾아서 "찾았어요!" 메시지와 함께 보여주자

// 동물들 목록
let animals = ["사자", "고양이", "강아지", "고릴라", "토끼"];

// "고"로 시작하는 첫 번째 동물 찾기
let animalStartsWithGo = animals.find(function(animal) {
    return animal.startsWith("고"); // 각 동물이 "고"로 시작하는지 확인
});

// 그 동물의 위치 찾기
let animalIndex = animals.findIndex(function(animal) {
    return animal.startsWith("고"); // 각 동물이 "고"로 시작하는지 확인
});

console.log("동물들:", animals);
console.log("찾았어요! '고'로 시작하는 동물은:", animalStartsWithGo); // "고양이"
console.log("그 동물은 " + (animalIndex + 1) + "번째에 있어요!");      // 2번째

Ex2) 키가 150cm 이상인 친구를 찾아서 "키 큰 친구 발견!" 메시지를 띄워보자

// 친구들의 키 정보
let students = [
    { name: "철수", height: 145 },
    { name: "영희", height: 152 },
    { name: "민수", height: 148 },
    { name: "지은", height: 155 }
];

// 키 150cm 이상인 첫 번째 친구 찾기
let tallStudent = students.find(function(student) {
    return student.height >= 150; // 각 친구의 키가 150cm 이상인지 확인
});

console.log("친구들:", students);
if (tallStudent) { // 찾은 친구가 있는지 확인
    console.log("키 큰 친구 발견! " + tallStudent.name + "(" + tallStudent.height + "cm)");
} else {
    console.log("키 150cm 이상인 친구가 없어요");
}

Ex3) 짝수를 찾아서 "첫 번째 짝수는 ○○이에요!" 메시지를 보여주자

// 숫자들 목록
let numbers = [1, 3, 7, 8, 5, 12, 9];

// 첫 번째 짝수 찾는 기능 만들기
function findFirstEvenNumber(numArray) {
    let evenNum = numArray.find(function(num) {
        return num % 2 === 0; // 각 숫자가 2로 나눈 나머지가 0인지 확인 (짝수 판별)
    });

    let evenIndex = numArray.findIndex(function(num) {
        return num % 2 === 0; // 각 숫자가 2로 나눈 나머지가 0인지 확인 (짝수 판별)
    });

    if (evenNum) { // 짝수를 찾았는지 확인
        console.log(`첫 번째 짝수는 ${evenNum}이에요! (${evenIndex + 1}번째 위치)`);
        return { number: evenNum, index: evenIndex }; // 결과 정보 묶음 반환
    } else {
        console.log("짝수가 없어요");
        return null; // 찾지 못했음을 알려줌
    }
}

// 기능 사용하기
findFirstEvenNumber(numbers); // "첫 번째 짝수는 8이에요! (4번째 위치)"

🤔 심화 문제로 실력 확인하기

더 깊이 있는 문제들을 통해 findfindIndex에 대한 이해를 확인해보겠습니다.

Q1. find를 친구에게 설명한다면 어떻게 설명하겠나요?

정답: "find는 숨바꼭질 게임과 같아요. 여러 친구들 중에서 '빨간 모자를 쓴 친구'를 찾으라고 하면, 순서대로 확인하다가 빨간 모자를 쓴 첫 번째 친구를 찾으면 그 친구를 데려오고 게임이 끝나는 거예요."

Q2. 다음 코드의 결과를 예측해보세요.

let fruits = ["사과", "바나나", "사과", "포도"];
let result = fruits.find(fruit => fruit === "사과");

정답: "사과"가 출력됩니다. 배열에 "사과"가 두 개 있지만 find는 첫 번째로 조건에 맞는 것만 반환하기 때문입니다.

📚 13단원 복습 - 비동기 처리 기억하기

14단원을 계속 배우기 전에 지난 시간에 배운 비동기 처리에 대해 간단히 복습해볼까요?

복습 문제 1: setTimeout과 Promise 조합하기

// setTimeout을 Promise로 감싸서 사용하는 delay 함수를 만들어보세요

function delay(milliseconds) {
    return new Promise(function(resolve) {
        setTimeout(function() {
            resolve(); // 지정된 시간이 지나면 Promise를 완료 상태로 만들기
        }, milliseconds);
    });
}

// 사용법
async function example() {
    console.log("시작");
    await delay(2000); // 2초 기다리기
    console.log("2초 후 실행");
}

// 정답: setTimeout을 Promise로 감싸면 async/await와 함께 사용할 수 있습니다.

복습 문제 2: 연속 작업을 Promise로 처리하기

// 여러 작업을 순서대로 처리하는 방법을 보여주세요

function task1() {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log("작업 1 완료");
            resolve("결과1");
        }, 1000);
    });
}

function task2(result) {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log("작업 2 완료:", result);
            resolve("결과2");
        }, 1000);
    });
}

// Promise 체이닝으로 연속 작업
task1()
    .then(result => task2(result))
    .then(result => console.log("모든 작업 완료:", result));

// async/await으로 연속 작업
async function runTasks() {
    let result1 = await task1();
    let result2 = await task2(result1);
    console.log("모든 작업 완료:", result2);
}

// 정답: Promise 체이닝이나 async/await으로 연속 작업을 처리할 수 있습니다.

🧚‍♀️ 이야기로 다시 배우기: 도서관 사서의 책 찾기 서비스

마지막으로 findfindIndex를 하나의 이야기로 정리해볼게요.

우리 동네에는 정말 친절한 사서 선생님이 계신 도서관이 있어요. 이 사서 선생님에게는 핀드(Find) 선생님인덱스(Index) 선생님이라는 두 명의 뛰어난 조수가 있답니다.

어느 날, 한 학생이 도서관에 와서 "공룡에 관한 책이 있나요?"라고 물어봤어요. 도서관에는 수많은 책들이 순서대로 꽂혀 있었는데: 역사책, 과학책, 공룡책, 수학책, 또 다른 공룡책이 차례대로 놓여 있었답니다.

핀드 선생님은 책장의 맨 앞부터 차근차근 책을 찾기 시작했어요. 역사책... 아니야, 과학책... 아니야, 공룡책... 찾았다! 핀드 선생님은 그 공룡책을 직접 가져와서 학생에게 건네주었어요. 뒤에 또 다른 공룡책이 있다는 것도 알고 있었지만, 첫 번째 것만 찾으면 되니까 더 이상 찾지 않았답니다.

인덱스 선생님은 같은 방식으로 찾았지만, 책 대신 위치를 적은 쪽지를 건네주었어요. "책장에서 3번째 자리에 공룡책이 있어요!"라고 정확한 위치를 알려준 거죠.

만약 학생이 "우주선에 관한 책이 있나요?"라고 물어봤다면? 핀드 선생님은 "그런 책은 없어요(undefined)"라고 대답하고, 인덱스 선생님은 "찾을 수 없어요(-1)"라고 대답했을 거예요.

이처럼 findfindIndex조건에 맞는 첫 번째 것을 찾아주는 똑똑한 도서관 조수들이에요. 여러분도 이제 이 조수들의 도움을 받아서 배열에서 원하는 것을 쉽게 찾을 수 있게 되었답니다!

지금까지 findfindIndex의 모든 특성과 활용법을 자세히 알아보았습니다. 이 도우미들은 배열에서 원하는 것을 효율적으로 찾아주는 훌륭한 도구가 될 것입니다.

✅ 학습 완료 체크리스트

이번 시간에 배운 내용들을 모두 이해했는지 확인해보세요!

학습 내용 이해했나요?
find와 findIndex의 기본 개념
기본 사용법과 문법
주요 특징과 차이점
자주 하는 실수들
실전 예제 이해

📂 마무리 정보

오늘 배운 14.4.1 내용이 여러분의 자바스크립트 지식 상자에 잘 저장되었나요? 다음 시간에는 더 재미있는 내용으로 만나요!

기억할 점: 오늘 배운 내용을 꼭 연습해보시고, 궁금한 점이 있으면 언제든 다시 돌아와서 읽어보세요.


🚀 더 체계적인 JavaScript 학습을 원하신다면?
이 포스팅에서 다룬 내용을 실제로 실습해보세요!
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
📝 실시간 코드 실행 📊 학습 진도 관리 👥 체계적 커리큘럼
📚 171개 체계적 학습레슨 · 📋 855개 4지선다 연습문제 · 🆓 완전 무료 · ⚡ 즉시 시작