VIDEO LESSON
JavaScriptのfindLast():配列の末尾から条件に合う1件を取得するの解説動画
再生時間 7:30動画を別のタブで開く ↗
動画の字幕・文字起こしを読む
再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。
- 0:00こんにちは。
- 0:01今回はジャバスクリプトの配列メソッド、ファインドラストを紹介します。
- 0:07ファインドラストは、配列を末尾から先頭へ向かって調べ、条件に合った要素を一つだけ返すメソッドです。
- 0:15たとえば処理の履歴が並んだ配列から、最後に成功した記録を取り出す、といった場面で活躍します。
- 0:23よく似たメソッドにファインドがありますが、こちらは先頭から探すため、得られる答えが変わることがあります。
- 0:33この動画では、基本の書き方、引数と戻り値、ファインドとの違い、履歴検索の実例、
- 0:38そして注意点までを順に解説します。
- 0:43最後まで見れば、後ろから探す理由がはっきり分かります。
- 0:47なぜ末尾から探すのでしょうか。
- 0:50操作履歴や処理結果は、起きた順番に配列へ追加していくことが多いからです。
- 0:55新しい記録ほど後ろに並ぶので、最新の成功や直近の操作は末尾側にあります。
- 1:00末尾の要素を直接読むだけでは不十分です。
- 1:03最後の記録が失敗だった場合、その一つ前、さらに前へとさかのぼって探す必要があります。
- 1:09ファインドラストは、このさかのぼる検索をそのまま表現できます。
- 1:14条件に合う要素が見つかれば、その時点で検索を終えるので、一致する要素をすべて集める必要がない用途に向いています。
- 1:22探す方向が意図としてコードに残る点も利点です。
- 1:25基本の書き方を見ましょう。
- 1:27配列に続けてファインドラストと書き、かっこの中に判定関数を渡します。
- 1:33判定関数は必須の引数で、要素ごとに呼び出され、条件に合うときにトゥルーを返すように書きます。
- 1:41判定関数には、現在の要素、その添字、対象の配列そのものが、この順番で渡されます。
- 1:47第二引数のディスアーグは省略でき、通常の関数で書いた場合にディスの値として使うものを指定できます。
- 1:55アロー関数では変更できません。
- 1:58戻り値は、一致した要素そのものです。
- 2:01添字でも配列でもありません。
- 2:03一致がなければアンデファインドが返り、空の配列でも同じくアンデファインドです。
- 2:10ここで大切なのは、最後という言葉の意味です。
- 2:13ファインドラストが返すのは、条件に合う要素のうち、添字が最も大きいものです。
- 2:20日時を比べて最も新しいものを選ぶ処理ではありません。
- 2:24履歴を古い順に追加しているなら、末尾側ほど新しいという前提が成り立ちますが、
- 2:30受け取ったデータの並び順が保証されない場合は、そのままでは最新を選べません。
- 2:36先頭から探すファインドとの違いは、まさにこの方向です。
- 2:41同じ配列、同じ条件でも、ファインドは前から最初の一致、ファインドラストは後ろから最初の一致を返します。
- 2:49用途に合わせて選び分けましょう。
- 2:52対応環境を確認しましょう。
- 2:53ファインドラストは、二千二十二年八月以降に主要ブラウザーで利用できるようになった、
- 2:57比較的新しい機能です。
- 3:00ノードジェイエスでは、バージョン十八で導入されました。
- 3:03ドムに依存しないため、ブラウザーでもノードジェイエスでも、同じコードが動きます。
- 3:08ただし古いブラウザーや組み込みのウェブビューでは使えないことがあります。
- 3:13利用前に、タイプオフでアレイのプロトタイプにファインドラストが関数として存在するか確かめてください。
- 3:19未対応のまま呼び出すと、タイプエラーになります。
- 3:22新しく環境を用意する場合は、サポート中のエルティーエス版を使うのがおすすめです。
- 3:27ここからは実例です。
- 3:29成功と失敗が混ざった実行履歴から、ステータスがサクセスの記録を探します。
- 3:34履歴は四件で、ジョブエーとジョブシーが成功、ジョブビーとジョブディーが失敗です。
- 3:39コードは外部通信も追加ライブラリーも使わない、コピーしてそのまま実行できる形にします。
- 3:45判定関数では、各要素のステータスがサクセスかどうかを比べます。
- 3:50検索は末尾のジョブディーから始まります。
- 3:52ジョブディーは失敗なので条件に合わず、一つ前のジョブシーで一致して、そこで検索が終わります。
- 3:59スライドのコードと一緒に、探す順番を追ってみてください。
- 4:03実行結果を確認しましょう。
- 4:05取り出されるのはジョブシーで、処理件数は八件です。
- 4:08調べた添字は三、二の順で、先頭側の二件は調べていません。
- 4:12一致した時点で終わるため、無駄な走査がありません。
- 4:16また、元の配列の並びはエー、ビー、シー、ディーのまま変わりません。
- 4:21ファインドラストは配列を反転させるような操作をしないからです。
- 4:25さらに、取り出したオブジェクトはコピーではなく、元の配列の要素と同じ参照です。
- 4:31あとからプロパティを書き換えると、元の配列から見える値も変わる点は覚えておきましょう。
- 4:37待機中の記録を探した場合は、アンデファインドが返ります。
- 4:41見つからない場合の扱いは、実務でとても重要です。
- 4:45検索結果が必ず存在するとは限りません。
- 4:47成功の記録が一つもない配列で探せば、結果はアンデファインドになります。
- 4:52そのままプロパティを読もうとすると、タイプエラーが発生して処理が止まります。
- 4:58必ず、結果がアンデファインドかどうかを先に確認してから、プロパティを参照してください。
- 5:04また判定関数の中で例外が発生した場合も、検索は中断され、例外は呼び出し元へ伝わります。
- 5:11なお、要素としてアンデファインド自体が保存されている配列では、戻り値だけでは見つからなかったのか、
- 5:16その値を見つけたのかを区別できません。
- 5:21データの設計も合わせて確認しましょう。
- 5:23次は、非同期の判定関数を渡す落とし穴です。
- 5:27判定関数をエイシンク付きで書くと、一見正しく動きそうに見えます。
- 5:32しかしエイシンク関数はプロミスを返し、プロミスのオブジェクト自体は真として評価されてしまいます。
- 5:39そのため条件の内容にかかわらず、末尾の要素が選ばれてしまいます。
- 5:44ファインドラストの結果にアウェイトを付けても、判定関数を待つ動作には変わりません。
- 5:50通信の結果で判定したい場合は、先に結果を取得して通常の値にそろえるか、末尾から回すループの中でアウェイトを使ってください。
- 5:59判定は同期処理で書く、という原則を守りましょう。
- 6:03細かな注意点を二つ押さえます。
- 6:06一つ目は、空き要素の扱いです。
- 6:08要素が抜けた疎な配列では、空き要素も判定の対象になり、値はアンデファインドとして扱われます。
- 6:16そのため、判定関数で無条件にプロパティを読むと、例外になることがあります。
- 6:22二つ目は、検索中の変更です。
- 6:24判定関数の中で配列や要素を書き換えると、結果を追いにくくなります。
- 6:30検索と更新は分けて書くのが、実務では扱いやすい設計です。
- 6:34また、条件に合う要素が先頭側にしかない場合は、結局配列全体を調べます。
- 6:40巨大な履歴を同じ条件で何度も検索するなら、記録を追加する時点で最後の該当要素も一緒に保持する方法を検討してください。
- 6:50最後に活用場面とまとめです。
- 6:52ファインドラストは、追加順が保証されたジョブ履歴から最後の成功記録を選ぶ、
- 6:57操作ログから特定の利用者が最後に行った操作を取り出す、古い順に並んだ通知から最後の未読を選ぶ、
- 7:02といった場面に向いています。
- 7:07導入するときは、三つの点を確認してください。
- 7:10後ろほど新しいという前提があるか。
- 7:12見つからなかった場合の処理を用意しているか。
- 7:16判定が同期処理になっているか。
- 7:18この三点がそろえば、履歴検索を短く読みやすくまとめられます。
- 7:23配列を壊さず、方向を明示して一件だけ取る。
- 7:26それがファインドラストの持ち味です。
- 7:28お疲れさまでした。
この動画で学べること
Array.prototype.findLast()で配列の末尾から条件に合う要素を探す方法を解説。引数・戻り値、ブラウザーとNode.jsの実行手順、履歴検索の実例と非同期処理の注意点を学べます。
解説記事・サンプルコードを読む:JavaScriptのfindLast():配列の末尾から条件に合う1件を取得する →