JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

【JavaScript】ネストされたオブジェクトの階層の深さ(depth)を再帰的に求める方法

問題の概要

JavaScriptでは、childrenプロパティで子要素を持つオブジェクトが、次のように何段階にもネストした配列として表現されることがあります。

const arr = [{
    id: 0, children: []
}, {
    id: 1, children: [{
        id: 2, children: []
    }, {
        id: 3, children: [{
            id: 4, children: []
        }]
    }]
}];

今回の課題は、この配列を受け取り、各ネストされたオブジェクトにdepth(階層の深さ)プロパティを割り当てる再帰関数 assignDepth() を作成することです。具体的な期待値は以下のとおりです。

  • 最上位に位置する id 0id 1 のオブジェクト → depth: 0
  • id 1 の内部にネストされた id 2id 3depth: 1
  • さらに id 3 の内部にネストされた id 4depth: 2

コード例:assignDepth() の実装

この処理はシンプルな再帰関数で実現できます。配列の末尾に到達するまで、サブオブジェクトを繰り返し走査していく仕組みです。

const arr = [{
    id: 0, children: []
}, {
    id: 1, children: [{
        id: 2, children: []
    }, {
        id: 3, children: [{
            id: 4, children: []
        }]
    }]
}];

const assignDepth = (arr, depth = 0, index = 0) => {
    if(index < arr.length){
        // 現在のオブジェクトに深さを割り当てる
        arr[index].depth = depth;
        // 子要素があれば、深さを1増やして子配列に対して再帰呼び出し
        if(arr[index].children.length){
            return assignDepth(arr[index].children, depth + 1, 0);
        };
        // 子要素がなければ、同じ配列の次の要素へ進む
        return assignDepth(arr, depth, index + 1);
    };
    return;
};
assignDepth(arr);
console.log(JSON.stringify(arr, undefined, 4));

実行結果

コンソールには次のように出力されます。すべてのオブジェクトに正しく depth プロパティが追加されていることが確認できます。

[
    {
        "id": 0,
        "children": [],
        "depth": 0
    },
    {
        "id": 1,
        "children": [
            {
                "id": 2,
                "children": [],
                "depth": 1
            },
            {
                "id": 3,
                "children": [
                    {
                        "id": 4,
                        "children": [],
                        "depth": 2
                    }
                ],
                "depth": 1
            }
        ],
        "depth": 0
    }
]

仕組みの解説

この関数のロジックを順番に整理すると、次のステップで構成されています。

  1. 継続条件のチェック: index が配列の長さ未満であることを確認し、未満であれば処理を続けます。
  2. depth の割り当て: 引数で受け取った depth を現在のオブジェクトに設定します。
  3. 子要素の探索: children 配列に要素がある場合は、depth + 1 を渡して子配列に対して再帰呼び出しを行います。
  4. 次の要素への移動: 子要素がない場合は、同じ配列内で index + 1 に進みます。
  5. 終了: index が配列の長さに達した時点で再帰を終了し、処理完了となります。

このように再帰を活用すれば、どれほど深くネストされたデータ構造でも、木構造をたどりながら各ノードの階層レベルを自動的に計算できます。ツリーメニュー、カテゴリ構造、組織図など、階層データを扱う場面で非常に役立つテクニックなので、ぜひマスターしておきましょう。

  1. JavaScriptで2つのオブジェクトをマージする方法を解説

    JavaScriptでは、スプレッド構文(...)を使うことで、2つのオブジェクトを簡単に1つにマージ(結合)できます。各オブジェクトの前に「...」を付けて新しいオブジェクトリテラル内に展開するだけで、すべてのプロパティが統合されたオブジェクトが生成されます。以下に、2つのJavaScriptオブジェクトをマージするコードの例を示します。コード例<!DOCTYPE html> <html lang=ja> <head> <meta charset=UTF-8 /> <meta name=viewport content=width=dev

  2. JavaScriptで値に基づいてオブジェクトをグループ化する方法

    JavaScriptでは、reduce()メソッドを活用することで、配列内のオブジェクトを特定の値(プロパティ)に基づいて効率的にグループ化できます。たとえば、複数人のデータを「年齢」ごとにまとめたい場合などに役立ちます。ここでは、実際に動作するサンプルコードをもとに、実装手順と仕組みをわかりやすく解説します。 サンプルコード <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewpo