JavaScriptで配列を再帰的にループし、一致する要素の数を返す方法
ネストされた(入れ子構造の)配列の中から、指定した検索語が出現する回数を数える関数、たとえば searchRecursively() を作成してみましょう。この関数は配列と検索クエリを受け取り、そのクエリが配列全体に合計何回登場するかを返します。
例として、次のような配列が与えられた場合を考えてみます。
const names = ["rakesh", ["kalicharan", "krishna", "rakesh", "james", ["michael", "nathan", "rakesh", "george"]]];
このとき、
searchRecursively(names, 'rakesh');
は 3 を返す必要があります。「rakesh」は配列全体で合計3回出現しているためです。
それでは、この再帰関数のコードを実際に書いてみましょう。
コード例
const names = ["rakesh", ["kalicharan", "krishna", "rakesh", "james",
["michael", "nathan", "rakesh", "george"]]];
const searchRecursively = (arr, query, count = 0, len = 0) => {
if(len < arr.length){
if(Array.isArray(arr[len])){
return searchRecursively(arr[len], query, count, 0);
};
if(arr[len] === query){
return searchRecursively(arr, query, ++count, ++len);
};
return searchRecursively(arr, query, count, ++len);
};
return count;
};
console.log(searchRecursively(names, "rakesh"));
出力
コンソールには次のように表示されます。
3
コードの仕組み
この関数の動作を順番に見ていきましょう。
- デフォルト引数:
count(一致した数)とlen(現在のインデックス)は初期値 0 で呼び出されます。 - 再帰処理: インデックス
lenが配列の長さに達するまで、自身を呼び出し続けます。 - ネスト判定: 現在の要素が配列(
Array.isArray()で判定)であれば、その配列に対して再帰的に検索を行います。これにより、どれだけ深く入れ子になっていても対応できます。 - 一致判定: 要素がクエリと一致すれば
countをインクリメントし、次の要素へ進みます。 - 終了条件: 配列の末尾に到達した時点で、累積された
countを返します。
よりシンプルな代替方法:flat() を活用する
再帰を自分で書かなくても、Array.prototype.flat(Infinity) を使えば多次元配列を一度に平坦化できるため、filter() と組み合わせるだけで同じ結果が得られます。
const countOccurrences = (arr, query) =>
arr.flat(Infinity).filter(item => item === query).length;
console.log(countOccurrences(names, "rakesh")); // 3
この方法ならコードが簡潔になり、ネストの深さを気にせず安全にカウントできるのがメリットです。用途に応じて、再帰による実装と使い分けるとよいでしょう。
-
JavaScriptで配列をループ処理する方法まとめ|for文・while文・do…while文の使い方
JavaScriptには、配列をループ処理するためのさまざまな方法が用意されています。それぞれの特徴を理解して使い分けることで、より効率的で読みやすいコードを書くことができます。本記事では、代表的なループ構文の基本と実行例をわかりやすく解説します。 JavaScriptのforループ まずは基本となるforループから見ていきましょう。JavaScriptのforループには主に2つの形式があります。1つ目は「初期化式・条件式・更新式」を指定する形式です。最初に初期化ステートメントを実行し、各イテレーションのたびに更新式を実行してから条件式を評価します。条件がtrueである限り、ループは繰り返され
-
JavaScriptでオブジェクトを含む「配列の配列」をループ処理する方法
JavaScriptでオブジェクトを含む多次元配列をループするには?JavaScriptでは、オブジェクトを含む配列の配列(入れ子構造の配列)をループ処理する際、forEach()メソッドをネストして使用し、さらにfor...inループで各オブジェクトのプロパティにアクセスするのが一般的な方法です。以下に、具体的な実装例を紹介します。コード例<!DOCTYPE html> <html lang=ja> <head> <meta charset=UTF-8 /> <meta name=viewport content=width=device