配列の中から条件に合う要素を探す場面はJavaScript開発でとても多いです。特に「複数の条件」を組み合わせて最初に見つかったものを取得したいという要求は頻繁に出てきます。このような場面でArray.prototype.findを賢く使いこなす方法を理解できれば、コードの読みやすさもパフォーマンスも格段に向上します。基礎知識から実践例、最新メソッドの紹介まで、実用的な情報を豊富に盛り込んでいきます。
目次
JavaScript find 複数 条件 を使って最初の一致を取得する方法
JavaScriptの配列に対して、複数の条件を組み合わせて「最初にマッチする要素」を取得するための基本的な方法を解説します。複数条件とは「プロパティAがこうであって、プロパティBがこうでない」、あるいは「条件1または条件2」のような論理的結合を意味します。findメソッドは複数の条件を含むコールバック関数を渡せるため、ANDやORを適用できます。
複数条件をANDで指定する
第一に、条件をすべて満たす要素を探したい場合です。コールバック関数内で論理AND演算子(&&)を使って複数のチェックを連結します。たとえばユーザーオブジェクトで年齢が20以上かつステータスがアクティブなものを最初に取得するようなケースです。これにより「両方の条件を満たす最初の要素」が返ってきます。
例:
const users = [
{ name: 'Alice', age: 25, active: true },
{ name: 'Bob', age: 30, active: false },
{ name: 'Carol', age: 20, active: true },
];
const result = users.find(user => user.age >= 20 && user.active);
このresultには最初に条件を満たすAliceのオブジェクトが返ります。
複数条件をORで指定する
次に、どれか一つの条件を満たせば良い場合、論理OR演算子(||)を使います。複数のプロパティのいずれかに指定値が含まれていればマッチするケースなどに有効です。複雑なフィルター機能を実装する際にはこのOR条件を使って柔軟な検索ロジックを作ります。
例:
const items = [
{ id: 1, type: 'book', color: 'red' },
{ id: 2, type: 'pen', color: 'blue' },
{ id: 3, type: 'book', color: 'green' },
];
const result = items.find(item => item.type === 'pen' || item.color === 'green');
この場合はtypeがpenまたはcolorがgreenの最初の要素、つまりid:2のオブジェクトが返ります。
ネストしたオブジェクトや配列を条件に含む場合
条件がオブジェクトや配列の中のプロパティにまたがる場合、コールバック関数内で安全にアクセスする仕組みを使います。optional chainingを使ってundefined参照を避けたり、配列のsomeメソッドやincludesを使えば複数値の比較が簡潔に書けます。複数階層のオブジェクトや子配列に対する条件をAND/ORで組むケースに有効です。
例:
const products = [
{ id: 1, tags: ['sale','new'], price: 100 },
{ id: 2, tags: ['clearance'], price: 50 },
{ id: 3, tags: null, price: 75 },
];
const result = products.find(p =>
(p.tags?.includes('sale') || p.tags?.includes('clearance')) && p.price <= 100
);
このようにして複雑な条件の組み合わせを明示的に書けます。
filterとの違いおよび用途の使い分け
複数条件で要素を探す際、findとfilterのどちらを使うかを判断することが大切です。filterはすべての要素を調べて条件を満たすすべての要素を配列で返しますが、findは最初にマッチした要素を返してそこで処理を止めます。この性質により、必要な状況に応じて使い分けると効率的で読みやすいコードになります。
findが適しているケース
次のような状況ではfindの使用が望ましいです。
- 複数条件を満たす最初の1件だけを取得したい
- 処理対象の配列が大きく、走査を途中で止めたい
- コードの明確さを重視し、filterでの余分な走査を避けたい
filterが適しているケース
一方で、filterを使ったほうが良いケースもあります。
- 条件を満たす要素が複数あり、それら全てを取得したい
- 後で取得した複数の要素をマッピングしたりソートしたりしたい
- 複数のAND条件またはOR条件を網羅的に組み込むが、最終的なデータ処理で複数結果を処理する必要がある
パフォーマンスの観点からの比較
findは最初にマッチした時点でループを止めるので、マッチ要素が先頭近くにある場合や条件が複雑でない場合には高速です。filterは配列全体を走査する必要があります。そのため、非常に大きな配列ではfilterのほうがコストが高くなることがあります。適切なメソッドを選ぶことで、検索を効率化できます。
最新機能:ES2023で追加されたfindLast・findLastIndexによる複数条件検索
最新のJavaScript仕様であるES2023では、配列の最後側から検索を行うメソッドが追加されました。これは「条件に合致する最後の要素」を取得したい場合に非常に便利です。findLastおよびfindLastIndexを使えば、配列を逆順にする手間をかけずに末尾から検索できます。
findLastの基本的な使い方
findLastはfindと同じようにコールバック関数を取り、配列の末尾から先頭に向かって要素を評価します。複数条件も同様に扱えます。例えば、AND条件またはOR条件を含むコールバックを渡して、「最後のマッチ要素」を取得できます。仕様の追加であり、モダンブラウザとNode.jsでサポートが広がっています。
findLastIndexの使いどころ
findLastIndexはfindLastと非常に似ていますが、返り値が要素そのものではなく、その要素のインデックスになります。配列の位置情報が必要な処理(例:削除や置換など)ではこちらが有用です。複数条件を使って、最後のマッチした要素の位置を取得する際にはfindLastIndexを使いこなしましょう。
サポート状況と注意点
findLastおよびfindLastIndexはES2023で導入された機能で、主要なモダンブラウザおよび最新のNode.jsでのサポートが進んでいます。ただし、一部の古いブラウザでは未対応のこともあるため、必要に応じてポリフィルやBabelなどで対応可能性を確認しておくことが望ましいです。
実践的なコード例集:複数条件検索で使えるパターン
ここでは複数条件を使った具体例をいくつか示します。実際の開発シーンで使いやすいように、組み合わせやネスト、動的な条件などを含めたコードを取り上げます。
複数条件と動的条件の組み合わせ
検索条件がユーザー入力などで動的に変わる場合、条件式を組み立てやすくしておくと保守性が上がります。AND/OR条件をまとめてひとつの述語関数にする、条件を省略可能にする工夫などがポイントです。
動的条件の例:
function createPredicate({ minPrice, maxPrice, category, inStock }) {
return item =>
(minPrice == null || item.price >= minPrice) &&
(maxPrice == null || item.price <= maxPrice) &&
(category == null || item.category === category) &&
(inStock == null || item.stock > 0);
}
const items = [
{ id: 1, price: 50, category: 'book', stock: 0 },
{ id: 2, price: 150, category: 'book', stock: 3 },
{ id: 3, price: 90, category: 'toy', stock: 5 },
];
const result = items.find(createPredicate({ minPrice: 80, category: 'book' }));
このようにすることで、条件が与えられていない場合にはその条件を無視できます。
OR条件が複雑な場合の処理例
OR条件が複数あると論理式が長くなりがちです。配列にpredicate関数をまとめてsomeを使うなどのパターンで整理できます。
const conditions = [
item => item.type === 'electronics',
item => item.tags?.includes('sale'),
item => item.color === 'red'
];
const result = items.find(item => conditions.some(fn => fn(item)));
このように条件をまとめておけば、新しい条件を追加する際も簡単になります。
最後または最初を状況に応じて使い分ける例
たとえば「最新の注文」や「最後に追加されたエントリー」など、後ろから検索したい状況があります。その場合findLastを使います。逆に「最初に条件にマッチするもの」を取りたいときはfindを使います。条件はAND/ORで組み込めます。
const orders = [
{ id: 1, status: 'pending' },
{ id: 2, status: 'completed' },
{ id: 3, status: 'completed' },
];
const latestCompleted = orders.findLast(order => order.status === 'completed');
const firstPendingOrCompleted = orders.find(order => order.status === 'pending' || order.status === 'completed');
よくある間違いとその回避策
複数条件を使うときに犯しやすいミスと、それを避けるための実践的なコツをまとめます。これらを理解しておくことでバグが減り、コードの品質が向上します。
条件の優先順位を誤る
ANDとORを混ぜる際に論理式の評価順を誤って意図と違う結果になることがあります。括弧で明示的に優先順位を示すか、述語関数を分割して可読性を保つようにします。複数のORを含む式では特にこの問題が顕著です。
undefinedやnullの扱い忘れ
ネストしたオブジェクトや配列の場合、プロパティが存在しないケースがあるため、optional chaining(?.)を使って安全にアクセスするか、条件式でnullチェックを入れておくことが重要です。存在しないプロパティにアクセスするとエラーになります。
要素が見つからない場合のundefinedへの対応
findやfindLastは要件を満たす要素が見つからないとundefinedを返します。undefinedを直接扱おうとしてプロパティ参照をすると実行時エラーになるため、返り値のチェックを必ず行うかoptional chainingを併用します。
まとめ
JavaScriptでfindを使って複数条件を組み合わせることで、最初にマッチする要素を効率よく取得できます。AND演算子とOR演算子、ネストされたオブジェクトアクセスや動的条件といったテクニックを駆使すれば柔軟な検索が可能になります。また、より新しい環境ではES2023で追加されたfindLastやfindLastIndexを使うことで、配列の後ろから検索を行うことも可能です。
filterとの使い分けも重要で、目的に応じて最適な方法を選ぶことでパフォーマンスとコードの明瞭性を両立できます。条件の優先順位やundefined対策など、よくある落とし穴を防ぐ工夫も忘れずに入れていきましょう。これらを押さえておけば「JavaScript find 複数 条件」に関する検索意図にも応える充実した内容となります。
コメント