JavaScriptの配列操作は、モダンなWebアプリケーション開発において、最も頻繁に行われる処理の一つと言えます。
2026年現在、JavaScript(ECMAScript)の進化により、私たちは配列内の要素を検索するために多くの選択肢を持つようになりました。
適切なメソッドを選択することは、コードの可読性を高めるだけでなく、アプリケーションの実行速度を最適化するためにも非常に重要です。
この記事では、JavaScriptの配列検索における主要なメソッドの使い分けから、大規模データを扱う際の実践的なテクニックまで詳しくご紹介します。
基本的な値の検索メソッド
配列の中に特定のプリミティブ値(数値や文字列など)が含まれているかを確認する場合、最もシンプルで直感的なメソッドが用意されています。
存在確認に最適なincludesメソッド
includesメソッドは、配列に特定の要素が含まれているかどうかを真偽値(true/false)で返します。
条件分岐の中で「値があるかないか」だけを知りたい場合に、最も読みやすいコードを書くことができます。
// 数値配列の定義
const numbers = [10, 20, 30, 40, 50];
// 値が存在するか確認
const hasThirty = numbers.includes(30);
console.log(hasThirty);
// 存在しない値を確認
const hasOneHundred = numbers.includes(100);
console.log(hasOneHundred);
true
false
以前はindexOfの戻り値が-1でないことを確認する手法が一般的でしたが、現在は意図が明確なincludesを使用することが推奨されます。
インデックスを取得するindexOfとlastIndexOf
値が存在する場所(インデックス番号)を知りたい場合には、indexOfメソッドを使用します。
indexOfは配列の先頭から検索を開始し、最初に見つかった要素のインデックスを返します。
もし要素が見つからなかった場合は-1を返すという特性があります。
const fruits = ['apple', 'banana', 'orange', 'apple'];
// 最初に見つかった'apple'のインデックスを取得
const firstAppleIndex = fruits.indexOf('apple');
console.log(firstAppleIndex);
// 最後に見つかった'apple'のインデックスを取得
const lastAppleIndex = fruits.lastIndexOf('apple');
console.log(lastAppleIndex);
0
3
lastIndexOfは配列の末尾から検索を開始するため、重複する要素がある場合に使い分けが可能です。
条件を指定して要素を検索するメソッド
単なる値の比較ではなく、「特定のプロパティを持つオブジェクト」や「特定の条件を満たす数値」を探す場合には、コールバック関数を利用するメソッドが必要です。
最初に一致する要素を返すfindメソッド
findメソッドは、指定したテスト関数を満たす最初の要素そのものを返します。
ユーザー一覧の中から特定のIDを持つユーザーオブジェクトを抽出するようなケースで非常に役立ちます。
// ユーザー情報の配列
const users = [
{ id: 1, name: '田中', role: 'admin' },
{ id: 2, name: '佐藤', role: 'editor' },
{ id: 3, name: '鈴木', role: 'viewer' }
];
// idが2のユーザーを検索
const targetUser = users.find(user => user.id === 2);
console.log(targetUser);
// 条件に合致しない場合
const unknownUser = users.find(user => user.id === 999);
console.log(unknownUser);
{ id: 2, name: '佐藤', role: 'editor' }
undefined
findで見つからなかった場合の戻り値はundefinedになるため、結果を利用する前にチェックを行うのが安全です。
インデックスを特定するfindIndexメソッド
findと同様の条件で検索し、要素そのものではなくその位置を知りたいときにはfindIndexを使用します。
特定の要素を配列から削除したり、特定の位置にあるデータを更新したりする際に多用されます。
const scores = [65, 80, 95, 40, 75];
// 90点以上の最初の要素のインデックスを取得
const highScorerIndex = scores.findIndex(score => score >= 90);
console.log(highScorerIndex);
2
配列の後ろから検索するfindLastとfindLastIndex
ES2023で導入され、現在の2026年では完全に標準として定着しているのがfindLastとfindLastIndexです。
これまでは配列を一度reverse()してから検索するなどの工夫が必要でしたが、これらのメソッドにより元の配列を破壊せずに末尾から効率よく検索できるようになりました。
const transactions = [
{ id: 1, amount: 100, status: 'completed' },
{ id: 2, amount: 500, status: 'pending' },
{ id: 3, amount: 200, status: 'completed' },
{ id: 4, amount: 300, status: 'pending' }
];
// 最後に行われた'pending'状態の取引を取得
const lastPending = transactions.findLast(t => t.status === 'pending');
console.log(lastPending);
{ id: 4, amount: 300, status: 'pending' }
複数の要素や条件の合致を確認する手法
「一つだけ探す」のではなく、条件に合うものをすべて抽出したり、配列全体の傾向を調べたりする場合のメソッドを確認しましょう。
条件に合うすべての要素を抽出するfilterメソッド
filterメソッドは、テスト関数を満たすすべての要素を含む新しい配列を生成します。
検索という文脈では、「特定のカテゴリに属するアイテムをすべてリストアップする」といった用途に適しています。
const products = [
{ name: 'PC', category: 'tech' },
{ name: 'Apple', category: 'food' },
{ name: 'Monitor', category: 'tech' }
];
// カテゴリが'tech'のものをすべて抽出
const techProducts = products.filter(p => p.category === 'tech');
console.log(techProducts);
[ { name: 'PC', category: 'tech' }, { name: 'Monitor', category: 'tech' } ]
もし条件に一致するものがなければ、空の配列[]が返されるため、undefinedを気にする必要がない点も特徴です。
存在の有無を真偽値で確認するsomeとevery
「配列の中に条件を満たすものが一つでもあるか」を確認するにはsomeメソッドを使います。
一方で、「すべての要素が条件を満たしているか」を確認するにはeveryメソッドが最適です。
const ages = [18, 22, 30, 15, 45];
// 未成年(20歳未満)が一人でも含まれているか
const hasMinor = ages.some(age => age < 20);
console.log(hasMinor);
// 全員が成人(20歳以上)か
const isAllAdult = ages.every(age => age >= 20);
console.log(isAllAdult);
true
false
これらのメソッドは、条件が確定した時点でループを終了(短絡評価)するため、非常に効率的です。
検索メソッドの比較まとめ
用途に応じてどのメソッドを使うべきか、以下の表で整理します。
| メソッド名 | 戻り値 | 主な用途 |
|---|---|---|
includes | Boolean | 特定の値が含まれているかの確認 |
indexOf | Number | 特定のプリミティブ値の位置を取得 |
find | Element | undefined | 条件に合う最初の要素を取得 |
findIndex | Number | 条件に合う最初の要素の位置を取得 |
findLast | Element | undefined | 末尾から条件に合う要素を取得 |
filter | Array | 条件に合うすべての要素を取得 |
some | Boolean | 条件に合う要素が一つでもあるか確認 |
every | Boolean | すべての要素が条件に合うか確認 |
オブジェクト配列における実践的な検索テクニック
実務では、単純な比較ではなく、複数の条件を組み合わせた複雑な検索が必要になる場面が多いです。
複数のプロパティを条件にする高度な検索
findやfilterのコールバック関数内では、論理演算子を使用して複雑な条件を指定できます。
また、大規模なコードベースでは、検索ロジックを関数として外に出すことで再利用性とテストの容易性を確保します。
const inventory = [
{ id: 'a1', name: 'Laptop', stock: 5, price: 120000 },
{ id: 'b2', name: 'Mouse', stock: 0, price: 3000 },
{ id: 'c3', name: 'Keyboard', stock: 12, price: 8000 }
];
// 「在庫があり」かつ「価格が10000円以下」の商品を検索する関数
const isAffordableInStock = item => item.stock > 0 && item.price <= 10000;
const result = inventory.find(isAffordableInStock);
console.log(result);
{ id: 'c3', name: 'Keyboard', stock: 12, price: 8000 }
このように述語関数(Predicate)を定義することで、コードの宣言的な記述が可能になり、保守性が向上します。
パフォーマンスを意識した検索アルゴリズムの選択
配列の要素数が数千、数万と増えていく場合、検索メソッドの選択がパフォーマンスに与える影響を無視できなくなります。
大規模データにおける計算量(O記法)の考慮
ここまで紹介したfindやindexOfなどの標準メソッドは、すべて「線形探索」を行っています。
線形探索の計算量は O(n) であり、要素数が増えるほど処理時間は比例して長くなります。
もし頻繁に大量のデータから検索を行う必要がある場合は、配列のまま検索し続けるのではなく、データ構造をMapやSetに変換することを検討すべきです。
// 10万件のデータがあるとする
const largeData = Array.from({ length: 100000 }, (_, i) => ({ id: `id-${i}`, val: i }));
// 配列での検索 (O(n))
console.time('Array find');
largeData.find(item => item.id === 'id-99999');
console.timeEnd('Array find');
// Mapに変換 (初期化コストはあるが、検索はO(1))
const dataMap = new Map(largeData.map(item => [item.id, item]));
console.time('Map get');
dataMap.get('id-99999');
console.timeEnd('Map get');
一度Mapを作成してしまえば、それ以降の検索は一瞬で完了するため、同じデータに対して何度も検索を行うシナリオで非常に有効です。
二分探索(Binary Search)の活用
データが特定のルール(ID順など)でソートされている場合、O(log n) で検索可能な「二分探索」を利用できます。
JavaScriptの標準メソッドに二分探索はありませんが、自作するかライブラリを活用することで、超大規模データへの対応が可能になります。
2026年のモダンな開発環境においても、アルゴリズムの基本を理解しておくことは高度な最適化において欠かせません。
まとめ
JavaScriptには、配列検索のための強力で多様なメソッドが備わっています。
単純な値の有無を確認したいときは includes を使い、詳細な条件で要素を取得したいときは find や filter を活用しましょう。
また、ES2023以降の findLast などの新機能を活用することで、コードをよりシンプルに保つことができます。
一方で、データ量が極めて多い場合には、標準メソッドの限界を理解し、Mapへの変換やアルゴリズムの工夫といったパフォーマンス最適化を検討することがプロフェッショナルな開発には求められます。
用途に応じた最適なメソッドを選択し、クリーンで効率的なJavaScriptコードを記述していきましょう。
