【JavaScript】find()メソッドとは?配列の要素を簡単に検索する方法を初心者向けに解説

はじめに

JavaScriptでは、配列の中から条件に合った要素を探す作業がしばしば必要になります。
例えばユーザー情報を格納した配列の中から、特定のユーザーIDに合致するデータを探すようなケースが考えられます。
こうした要素検索の機能はさまざまな方法で実現できますが、その中でもとても便利なのがfind()メソッドです。

find()メソッドは、配列の要素に対して条件式を実行し、条件に合う要素を1つだけ返してくれます。
もし条件に合う要素がなければ、戻り値としてundefinedを返します。
また、filter()メソッドのように複数の要素をまとめて取得する場合とは異なり、最初に一致した要素を見つけた時点で処理が終了する仕組みになっています。

実際の開発現場でも、「ユーザーのプロフィールリストから、特定のユーザー情報だけを抽出したい」「在庫リストから商品コードに合う在庫を検索したい」といった用途で使われることが多いです。
初心者の皆さんにとっては、どこで使えば良いのか、どのように書けば良いのかが少しわかりづらいかもしれません。

しかし、ポイントをしっかり押さえれば扱いは難しくありません。
今回の記事では、基本的な使い方や活用シーン、似たメソッドとの比較、注意すべき点などを幅広く紹介していきます。

この記事を読むとわかること

  • JavaScriptのfind()メソッドの概要と特徴
  • 基本的な書き方と実務における具体的な使い所
  • filter()やfindIndex()など、似たメソッドとの違い
  • find()を使う時に気をつけたいポイントやパフォーマンス面

ここを一通り理解すれば、配列から効率よく要素を探せる方法がわかり、実際の開発でもスムーズに活用できるでしょう。

JavaScriptにおけるfind()とは

find()メソッドは、配列内を順番に走査して、コールバック関数がtrueを返す最初の要素を返します。
例えば、以下のように書くことで、条件式に合致した最初の要素が取得できます。

const foundItem = array.find((element) => {
  // 条件を記述
  return element === 'target';
});

この例では、配列arrayの中でelementが文字列'target'に一致した時点で、そのelementfoundItemとして返されます。
もし配列の中に'target'が存在しない場合は、foundItemはundefinedになります。

特徴としては、最初のマッチした要素のみを取得するという点が挙げられます。
似たようなメソッドとしてfilter()がありますが、filter()が条件に合った要素をすべて抽出して新しい配列として返すのに対して、find()はあくまで最初にヒットした一つの要素だけを返す点が大きな違いです。

また、find()メソッドを使う場合には、配列が空の場合や、いずれの要素も条件に合わない場合に備えて、戻り値がundefinedになることを想定する必要があります。
思わぬエラーを防ぐためには、「見つからなかったときはどう振る舞うのか?」を設計時に考えておくのが大切です。

実務の場面では、ユーザーリストのようにオブジェクトの配列を取り扱うケースが多いです。
例えば「特定のIDを持つユーザーを探したい」といった場面で活躍します。
ここでも、見つからなかったときには何かエラー表示をするのか、新しくユーザーを生成するのか、といったロジックを事前に決めておくとスムーズに開発できます。

find()の基本的な使い方

シンプルなサンプルコード

まずは基本的な文法を一つの例で示します。
以下は文字列の配列から、最初に'banana'に合致する要素を取得する例です。

const fruits = ['apple', 'banana', 'orange', 'banana'];
const result = fruits.find((fruit) => {
  return fruit === 'banana';
});
console.log(result); // "banana"

上記のコードでは、配列fruitsの先頭から順番に、fruitが'banana'に等しいかどうかを評価します。
最初に合致するのはインデックス1の要素ですので、その時点で'banana'が返されます。
その後、インデックス3にも'banana'がありますが、すでに最初の'banana'を返した時点でfind()メソッドの走査は終了しています。

このように、特定の値に対して最初にマッチする要素だけを取得したいときに便利です。

コールバック関数の構造

find()メソッドに渡すコールバック関数には、下記のパラメータを指定できます。

array.find((element, index, array) => {
  // 条件を記述し、booleanを返す
});
  • element: 現在評価している配列の要素
  • index: 現在評価している配列のインデックス
  • array: 元となる配列自体

実際の場面では、elementだけを使うケースが多いです。
しかし、インデックス情報が必要な場合や、配列全体を参照して追加の判定を行いたい場合には、indexやarrayを使って柔軟な条件式を組み立てることも可能です。

例えば、要素が特定の値である場合に加えて、その要素のインデックスが偶数かどうかで絞り込みたいといった場合には、indexを活用します。
次の例は、数値の配列から「値が10以上かつインデックスが偶数のとき」に最初に合致する要素を探すケースです。

const numbers = [3, 8, 12, 5, 20, 9];
const foundNumber = numbers.find((num, idx) => {
  return num >= 10 && idx % 2 === 0;
});
console.log(foundNumber); // 12

この例だと、インデックス2の値である12が先にヒットするので、find()は12を返して処理を止めます。
こうした活用方法もあるため、場面によってはindexやarrayを活用して判定ロジックをより細かく設定できるわけです。

実務での活用シーン

例: リストから特定のデータを抽出

例えば、ユーザー情報を保持した配列を考えてみましょう。
オブジェクトの配列があり、その中にはユーザーIDやユーザー名が格納されているケースです。
配列が大きくなると、単純なforループで回してif文を使って判定するのも手ですが、コード量が増えることがあります。

そのような場合にfind()を使うと、以下のように少ない行数で目的を達成できます。

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
];

const targetUser = users.find((user) => {
  return user.id === 2;
});

console.log(targetUser); 
// { id: 2, name: 'Bob' }

ここでは、ユーザーIDが2の要素にマッチした時点で、そのオブジェクトを返します。
もし見つからなかった場合はundefinedなので、何も見つからなかったときに備えて条件分岐を書いておけばエラーを防げます。

実務の観点で言うと、バックエンドから受け取ったデータの配列から「該当する商品コードを持つオブジェクトを探す」ようなシーンが典型です。
find()なら、必要な要素だけをすばやく取得できるので便利です。

例: フォーム入力の重複チェック

別の活用シーンとしては、ユーザーがフォームに入力したデータを既存の配列と照合して、重複がないかをチェックする状況が挙げられます。
例えば、すでに登録済みのメールアドレスと被っていないかを確認するような場面です。

const registeredEmails = ['test@example.com', 'hello@example.com'];

function isDuplicateEmail(email) {
  const duplicate = registeredEmails.find((item) => {
    return item === email;
  });
  return duplicate !== undefined;
}

const newEmail = 'test@example.com';
if (isDuplicateEmail(newEmail)) {
  console.log('すでに登録されているメールアドレスです。');
} else {
  console.log('新規登録が可能です。');
}

ここでは、すでに配列registeredEmailsに同じメールアドレスが存在するかどうかをfind()で調べています。
見つかれば重複と判断し、見つからなければ新規登録が可能といった分岐を行うわけです。
実務でもデータの重複チェックはよくある処理なので、find()が役立つ場面と言えます。

find()とfilter()の違い

find()とfilter()はどちらも「条件に合った要素を検索する」ために使われるメソッドです。
しかし、両者の動作にははっきりした違いがあります。

  • find(): 条件に合う最初の要素を返す。見つかった時点で走査を終了し、その要素を返す。
  • filter(): 条件に合うすべての要素を新しい配列として返す。見つかった要素を一括で取得し、走査は最後まで実施する。

この違いによって、使い分けのポイントが変わります。
例えば、ただ1つの要素を探し出すときにはfind()のほうが明示的かつコードが読みやすくなります。
一方、複数の要素をまとめて取得したいときにはfilter()を使うべきです。

また、実行速度という観点では、探したい要素が配列の先頭付近にある場合、find()のほうが早く返ってきます。
これは、一度条件を満たす要素が見つかった時点で処理を終了するからです。
filter()は最後まで検索を続けるので、要素がどこで見つかろうと配列全体を走査することになります。

ただし、配列の中で条件を満たす要素が存在しない場合は、find()も全体を走査することになるため、そこまで大きく速度差が出るわけではありません。
それでも、「一つだけ見つかれば十分」なシチュエーションであれば、より意図が伝わるfind()を使うのが良いでしょう。

findIndex()との比較

findIndex()は、見つかった要素そのものではなく、要素のインデックスを返すメソッドです。
動きとしては、find()と同じく条件に合う最初の要素を探し、発見したらそのインデックスを返し、見つからなければ-1を返します。

例えば、以下のように書くことができます。

const colors = ['red', 'green', 'blue', 'yellow'];
const targetIndex = colors.findIndex((color) => {
  return color === 'blue';
});

console.log(targetIndex); // 2

find()との使い分けは**「見つけた要素そのものが必要か、それともインデックスが必要か」**にかかっています。
例えば、その要素を後から削除したいとか、配列の特定の位置を別の値に置き換えたいといった場合にはインデックスが必要になります。
そのときにはfindIndex()が便利です。

一方、取り出した要素をそのまま何かの処理に渡したいとか、要素の値を使って別の処理を行いたいときには、find()が適しています。
両者は似ているようで、返される内容が根本的に違いますので、用途に応じて選択しましょう。

find()を使う際の注意点

undefinedが返る場合の対処

find()を実行しても条件に合う要素が一切見つからない場合は、戻り値としてundefinedが返ります。
そのため、実際の開発では「見つからない可能性」があることを前提に、戻り値を必ずチェックする必要があります。

例えば、以下のような書き方で、結果がundefinedであれば別の処理を行うように分岐できます。

const products = [
  { id: 10, name: 'Pen' },
  { id: 20, name: 'Notebook' }
];

const target = products.find((item) => {
  return item.id === 999; // 存在しないID
});

if (!target) {
  console.log('該当する商品が見つかりませんでした。');
} else {
  console.log('商品名:', target.name);
}

このように、見つからなかった場合にエラーメッセージを表示したり、新規データを登録したりするフローに繋げることが可能です。
もし戻り値をチェックせずにプロパティを参照しようとすると、TypeErrorが発生する場合があるので気をつけましょう。

オブジェクト配列での注意

オブジェクト配列に対してfind()を使う場合は、「比較したいプロパティ名が正しいか」「値の型が正しいか」に気を配ってください。
一見同じように見える値でも、実際には型が異なるケース(数値と文字列など)が存在するかもしれません。

また、部分一致ではなく完全一致を求める場合などには、正確な条件式を書くことが欠かせません。
例えば、文字列を部分的に含むかどうかを確かめたい場合、下のようにString.includes()を使った条件式を書くこともあります。

const employees = [
  { name: 'Tanaka Taro', department: 'Sales' },
  { name: 'Yamada Hanako', department: 'Development' }
];

const foundEmployee = employees.find((emp) => {
  return emp.name.includes('Tanaka');
});

console.log(foundEmployee);
// { name: 'Tanaka Taro', department: 'Sales' }

このように、オブジェクト配列はプロパティに文字列や数値など、さまざまな型の情報が入ります。
条件が複雑になると、「厳密に何を比較するか」をしっかり意識するのが大切です。

パフォーマンスに関する考え方

パフォーマンス面では、find()は「最初に条件を満たした要素を見つけるとそこで走査をやめる」という特徴から、巨大な配列の先頭付近に条件を満たす要素がある場合は有利です。
ただし、配列の後ろのほうに条件を満たす要素がある場合や、そもそも見つからない場合には、結果として配列全体を走査します。

たとえば、1万件や10万件といった比較的大きな配列を扱うとき、次のような点に注意すると良いでしょう。

  • 配列のサイズが非常に大きい場合、find()を連続で呼び出すのはコストがかかる
  • 条件に合う要素が確実に先頭にあるわけではない場合、全走査になることがある
  • 事前にインデックスを保持しておくなどの最適化を検討してもいい

ただし、初心者の方が最初から過度な最適化を意識しすぎるよりは、「見つかった瞬間に停止するので、filter()より無駄が少ないかもしれない」ぐらいの感覚で始めておくのがおすすめです。
本格的にパフォーマンスチューニングが必要になる場面なら、まずはプロファイリングで実際の負荷を測定してから対処を検討するほうが良いでしょう。

find()が1つの要素を探し出すのに特化しているため、複数の要素を一度に取得したい場面ではfilter()や他のアプローチを検討する必要があります。

よくある質問と回答

ここでは初心者の皆さんからよく寄せられる疑問を取り上げます。
find()メソッドを使いこなすうえで、基本的な疑問点を押さえておくと学習の効率が上がるでしょう。

find()で複数条件を指定するには?

コールバック関数の中に「複数の条件」を論理演算子(&&, ||)で組み合わせるだけです。
例えば、「数値が10以上かつ20以下である要素」を探すには以下のように書きます。

const nums = [5, 10, 15, 20, 25];
const found = nums.find((num) => {
  return num >= 10 && num <= 20;
});
console.log(found); // 10

ここでは10や15、20が該当しますが、最初にヒットする10が返されます。

空の配列に対してfind()を実行するとどうなる?

空の配列には要素が存在しないため、どんな条件を指定しても最初から条件を満たす要素はありません。
結果はundefinedが返されます。
こうしたケースを考慮して、find()の戻り値がundefinedになる可能性を常に考慮すべきです。

find()のコールバック関数を省略して書く方法はある?

ES6以降ではアロー関数が使えるため、シンプルな条件であれば1行に書くことも多いです。
例えば、先ほどの「数値が10以上」を探す例なら、下記のように書くことができます。

const numbers = [1, 5, 10, 15];
const found = numbers.find(num => num >= 10);
console.log(found); // 10

特に複雑な処理をしないなら、アロー関数を省略形で使うのがおすすめです。

find()は文字列にも使える?

find()は配列に対するメソッドなので、文字列そのものには直接使えません。
しかし、文字列を一文字ずつ要素に分割した配列を用意すれば、同様の考え方で利用できます。
もちろん、通常はそこまで細かく文字単位で探索する機会はあまり多くありません。

find()の結果をすぐに使わない場合はfilter()のほうが良い?

最初の1件だけを取得する必要がある場合にはfind()が最適です。
しかし、いくつも該当する可能性があって、それらを全部集めたい場合にはfilter()を使うのが適切でしょう。
条件に合う要素が複数あるときにfind()を使うと、最初の1件しか取得できません。

まとめ

JavaScriptのfind()メソッドを使えば、配列から特定の条件に合う要素を簡潔に探し出すことができます。
最初に合致した要素だけを返すという特性から、実務でも「特定のIDを持つレコードを探す」「既存データと重複しているか判定する」など、さまざまなシーンで活用されています。

filter()やfindIndex()といった似たメソッドとの違いを理解しておくと、「1つだけ必要なのか」「すべてを集めたいのか」「インデックスを求めるのか」といった要件に応じて使い分けがしやすくなります。
また、find()は条件を満たさない場合にはundefinedを返すので、戻り値のチェックが欠かせません。

配列操作はプログラミング初心者が最初にぶつかりやすい壁のひとつですが、書き方のパターンを覚えると難しくありません。
ぜひ今回の内容を参考に、JavaScriptでの配列検索を効率よく行ってみてください。

複雑な条件や巨大な配列を扱う場合には、事前のインデックス作成など別の方法も検討すると良いでしょう。
しかしまずはfind()メソッドの基本的な使い方を押さえることで、普段の開発をよりスムーズに進められます。

JavaScriptをマスターしよう

この記事で学んだJavaScriptの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。