【JavaScript】条件に一致する要素を即座に特定!findとfindIndexの完全活用ガイド

目次

概要

配列データの中から「特定のIDを持つ社員」や「条件に合致する最初のデータ」を抽出したい場合、find メソッドが最適です。

また、そのデータが配列の何番目にあるかという「位置情報」が必要な場合は findIndex を使用します。本記事では、社員名簿検索システムを題材に、これら2つのメソッドの実践的な使い分けを解説します。

仕様(入出力)

findfindIndex の比較

どちらもコールバック関数(テスト関数)が true を返した時点で探索を終了し、結果を返します。

メソッド目的戻り値(見つかった場合)戻り値(見つからなかった場合)
find条件を満たす データそのもの が欲しい要素の値undefined
findIndex条件を満たす 場所(インデックス) が欲しいインデックス (数値)-1

コールバック関数の引数

([現在の要素], [インデックス], [元の配列]) => 真偽値

  • 入力: テスト関数(検索条件)
  • 出力: 条件に合致した要素、またはインデックス

基本の使い方

1. 要素そのものを取得する (find)

オブジェクトの配列から、特定のプロパティを持つオブジェクトを探すのによく使われます。

const members = ['小林', '中林', '大林'];

// 「中」が含まれるメンバーを探す
const target = members.find(name => name.includes('中'));

console.log(target); // "中林"

2. 位置を取得する (findIndex)

要素の場所(順番)を特定したい場合に使用します。

const staffIds = [101, 202, 303, 404];

// IDが300以上の最初の位置を探す
const position = staffIds.findIndex(id => id >= 300);

console.log(position); // 2 (303のある位置)

コード全文(HTML / JavaScript)

社員IDを入力すると、名簿データから該当者を検索し、その詳細とリスト内の登録順を表示するシステムです。

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Employee Search System</title>
    <style>
        .search-card {
            font-family: 'Hiragino Kaku Gothic ProN', sans-serif;
            max-width: 450px;
            padding: 25px;
            border: 1px solid #e0e0e0;
            border-radius: 8px;
            background-color: #ffffff;
            box-shadow: 0 4px 6px rgba(0,0,0,0.05);
        }
        .input-group {
            margin-bottom: 20px;
        }
        label {
            display: block;
            margin-bottom: 8px;
            font-weight: bold;
            color: #555;
        }
        input[type="number"] {
            width: 100%;
            padding: 12px;
            border: 2px solid #ddd;
            border-radius: 6px;
            font-size: 1rem;
            box-sizing: border-box;
            transition: border-color 0.3s;
        }
        input[type="number"]:focus {
            border-color: #4a90e2;
            outline: none;
        }
        .result-area {
            padding: 15px;
            background-color: #f8f9fa;
            border-radius: 6px;
            min-height: 80px;
        }
        .found-name {
            font-size: 1.4rem;
            color: #333;
            margin: 0 0 5px 0;
            border-bottom: 2px solid #4a90e2;
            display: inline-block;
        }
        .found-meta {
            color: #666;
            font-size: 0.9rem;
            margin: 5px 0 0 0;
        }
        .error { color: #d9534f; font-weight: bold; }
    </style>
</head>
<body>

<div class="search-card">
    <div class="input-group">
        <label for="staff-id">社員番号検索 (1001〜)</label>
        <input type="number" id="staff-id" placeholder="IDを入力してください">
    </div>

    <div id="search-output" class="result-area">
        <p>検索結果がここに表示されます</p>
    </div>
</div>

<script src="employee_search.js"></script>
</body>
</html>

JavaScript

/**
 * 社員検索スクリプト
 * findとfindIndexを使用したデータ特定
 */

// 1. 社員データベース(配列)
const staffDirectory = [
    { id: 1001, name: '森', role: '部長' },
    { id: 1002, name: '小林', role: '課長' },
    { id: 1003, name: '大木', role: '主任' },
    { id: 1004, name: '中森', role: 'メンバー' },
    { id: 1005, name: '小木', role: 'メンバー' },
    { id: 1006, name: '大林', role: '新人' }
];

// DOM要素の取得
const idInput = document.getElementById('staff-id');
const outputArea = document.getElementById('search-output');

/**
 * 検索を実行する関数
 * @param {number} queryId 
 */
const findStaff = (queryId) => {
    // IDが入力されていない場合はクリア
    if (!queryId) {
        outputArea.innerHTML = '<p>検索結果がここに表示されます</p>';
        return;
    }

    // ★ findメソッド: オブジェクトそのものを取得
    const staff = staffDirectory.find((person) => person.id === queryId);

    if (staff) {
        // ★ findIndexメソッド: 配列内の位置を取得(0始まり)
        const index = staffDirectory.findIndex((person) => person.id === queryId);
        
        // 結果表示
        outputArea.innerHTML = `
            <h3 class="found-name">${staff.name} ${staff.role}</h3>
            <p class="found-meta">
                社員番号: ${staff.id}<br>
                名簿登録順: ${index + 1}番目
            </p>
        `;
    } else {
        // 見つからなかった場合
        outputArea.innerHTML = '<p class="error">該当する社員データはありません。</p>';
    }
};

// 入力イベントの監視
idInput.addEventListener('input', (e) => {
    const val = Number(e.target.value);
    findStaff(val);
});

カスタムポイント

  • 検索条件の柔軟化:person.id === queryId の部分を person.name === '文字列' に変更すれば名前検索になります。
  • 複雑なロジック:find(p => p.role === '部長' && p.id > 1000) のように、役職とIDを組み合わせた複合条件での検索も可能です。

注意点

  1. IEの非対応:findfindIndex はInternet Explorer(IE)では動作しません。レガシーブラウザ対応が必要な場合はPolyfillを導入するか、filter メソッドで代用(filter(...)[0])してください。
  2. パフォーマンス:配列の先頭から順にチェックするため、データ量が数万件〜と膨大な場合、後ろの方にあるデータの検索には時間がかかります。頻繁に検索する場合は、予めIDをキーにしたオブジェクト(Map)に変換しておくことを推奨します。

応用

findIndex を使ったデータの削除

ID指定でデータを削除したい場合、オブジェクト配列では splice の引数としてインデックスが必要です。

const users = [
    { name: '中林' },
    { name: '大森' }
];

// '大森' を削除したい
const targetIndex = users.findIndex(u => u.name === '大森');

if (targetIndex !== -1) {
    users.splice(targetIndex, 1);
}

console.log(users); // [{ name: '中林' }]

まとめ

配列内の特定のデータを扱う際、用途に応じて以下の通り使い分けます。

  • データの詳細(プロパティ)を知りたい・表示したい → find
  • データの更新や削除のために場所を知りたい → findIndex

両者は戻り値が「オブジェクト(または undefined)」と「数値(または -1)」で大きく異なるため、その後の条件分岐の書き方に注意して実装してください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次