記事
JavaScriptで配列を検索する方法は、やり方はさまざまあります。さまざまあるがため、便利である反面、どれを使うのがベストプラクティスなのか判断に迷うこともよくあります。
そんなときには、自分の中で、このような検索をしたい場合は、必ずこのメソッドを使おう。と、決めてしまうことがいいかと思っています。
配列の検索でよく使うメソッドは次の3つです。
- includes
- find
- filter
3つのメソッドは次のように使い分けるといいかと思います。
配列の中に特定の要素が含まれているかどうかだけを知りたい場合は、includesを使う。includesはtrueかfalseを返します。存在すればtrueで、存在しなければfalseを返します。
includesの代わりにindexOfを使って判断をすることもできます。includesがtrueかfalseを返すのに対し、indexOfは存在すれば配列のインデックスを返し、存在しなければ-1を返します。インデックスを知る必要がない場合は、includesを使った方が個人的にはシンプルでいいかと思っています。indexOfを使わざるを得ない用途は個人的にあまり思いつきません。
配列の中に条件にマッチした要素を取得する場合は、findかfilterを使います。マッチするかしないかの判断をするだけでなく、マッチした場合は要素の値を取得したい場合に使います。
条件にマッチした要素が複数存在した場合、最初にマッチした1つの要素だけを取得する場合はfindを使いますが、マッチした要素全てを取得したい場合はfilterを使います。filterの方がfindよりも詳細な情報を取得できるため、イレギュラー要素が発生した場合は、後から調査するために役立つかと思います。findは使わずに、filterしか使わないと決めてしまってもいいかと思います。
サンプル例
サンプルで次のような配列を作成しました。
var ary = ["滋賀県","京都府","大阪府","兵庫県","奈良県","和歌山県","滋賀県"]
var ret;
var msg;
配列の中に特定の要素が含まれているかを判断する場合、includesを使います。この場合「滋賀県」が含まれているため、includesはtrueを返します。
ret = ary.includes("滋賀県");
msg = ret ? "存在します" : "存在しません";
「愛知県」は含まれてないため、includesはfalseを返します。
ret = ary.includes("愛知県");
msg = ret ? "存在します" : "存在しません";
includesの代わりにindexOfを使うと次のようになります。「愛知県」は含まれないため、indexOfは-1を返します。含まれれば、配列のインデックスを返すため、必ず、0以上が返ってきます。
ret = ary.indexOf("愛知県");
msg = (ret => 0) ? "存在します" : "存在しません";
このように記述しても同じです。-1より小さい数(-2など)が返ってくることはありません。
ret = ary.indexOf("愛知県")
msg = (ret != -1) ? "存在します" : "存在しません";
配列の中から文字数が3の要素を選び出します。全角文字も1文字としてカウントされます。配列の中で「和歌山県」以外の要素は全て3文字です。配列の先頭要素から順番に検索して、3文字の条件に該当する「滋賀県」だけを返します。
ret = ary.find(el => el.length == 3);
条件に該当しない場合は、undefinedが返ります。文字数が1の要素は1つも存在しないため、この場合はundefinedが返ります。
ret = ary.find(el => el.length == 1);
findを使って「滋賀県」が含まれているかを調べることもできます。ただし、findを使った場合、配列の中に「滋賀県」が1つだけ存在するのか、複数存在するのかまでは分かりません。「滋賀県」が複数存在する場合、いくつ存在しているかを知りたいときは、filterを使えば分かります。
ret = ary.find(el => el == "滋賀県");
msg = (ret == "滋賀県") ? "存在します" : "存在しません";
文字数が3である要素を全て抜き出したいときは、filterを使います。先ほども書きましたが、findを使うと条件に該当する要素が複数存在していても、一番最初にマッチした1つの要素しか返しません。次の記述では、文字数が3以上の要素、つまり「和歌山県」以外の要素である、[ '滋賀県', '京都府', '大阪府', '兵庫県', '奈良県', '滋賀県' ]を返します。文字列で返すのではなく配列で返します。
ret = ary.filter(function(el) {
return el.length == 3;
});
次の記述では、配列で[ '滋賀県', '滋賀県' ]を返します。配列の中に「滋賀県」の要素値が2つ含まれるためです。findでは「滋賀県」が2つ含まれていても「滋賀県」1つを文字列として返します。この辺が、findとfilterの違いということになります。
ret = ary.filter(function(el) {
return el == "滋賀県";
});