JavaScriptで入れ子オブジェクトの全要素をループ・全て表示させる

JavaScriptで入れ子のオブジェクトがある時…

  • 2階層以上の入れ子を持つ
  • その全要素をループさせたい
  • ただし多重ループは使わない

英語では traverse とも呼ばれてます。

オブジェクトの階層(入れ子)を無視し、
並列に全要素を全て表示・探索したいってことです。

その方法をいくつか考えてみました。

1.再帰によるオブジェクト全要素のループ探索

初めは再帰を使ったループ方法

再帰というのを一言で説明すると……

  • ある再帰用の関数を用意する
  • その関数内で自分自身を呼び出す
  • 一定条件を満たすまで再帰を続ける

実を言うとあんまりいい方法でありません。

事実、ほとんどの再帰は単純ループで置き換えできます。

でも初めに再帰を使った方法でやってみました。

▼ 結果として次のようなコードに

▼ このコードの出力結果

再帰関数に渡されたオブジェクトに対してキーでループを回し、その要素がオブジェクトなら再帰を実行、値・配列・Object以外ならそのまま表示してます。

ここではオブジェクトかの判断条件として value.constructor === Object && !value.length  を使っており、配列・クラスインスタンスなどが誤検知されないようにしました。

ただ再帰の欠点は次のことです。

  • 再帰関数の呼び出しのコストが大きい
  • 巨大なオブジェクトの場合は不向き

もちろん数千個レベルなら問題ないです。

でも超巨大なオブジェクトだと時間がかかるかも

2.一重ループだけでオブジェクトの全要素を探索

お次は再帰も多重ループも使いません。

単純に1回だけのループでどうにかします。

▼ 実際に書いてみたコード例

▼ このコードの出力結果

スタック( stack )を用意し、初めに渡されたオブジェクトを入れます。このスタックにオブジェクトを次々と階層・入れ子を無視して入れることで全要素の探索をしてます。

具体的に書くなら for (let j in stack[0]) {...}  の内部でループ要素がオブジェクト(Object)ならスタックに積み、それ以外なら出力してるだけです。

あとはスタックが空になるまでループするだけ

Object・Array向けのtraverse専用ライブラリもある

ちなみにこんなライブラリとかもあります。

▼ substack/js-traverse

入れ子構造の配列・オブジェクトのtraverseができます。

※ ただしnpm専用ライブラリの模様

以上、JSでのオブジェクト全要素のループでした。

間違い・ご指摘はコメント欄からどうぞ、ではまた