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

【JavaScript】ネストしたJSONオブジェクトをドット記法でフラット化する方法

JavaScriptでは、APIレスポンスなどで受け取るJSONオブジェクトが、任意の深さまで入れ子(ネスト)になっていることがよくあります。このようなネスト構造を持つオブジェクトを、キーをドット記法で連結したフラットな1階層のオブジェクトへ変換したい場面は少なくありません。

例として、次のようなJSONオブジェクトを考えてみましょう。このオブジェクトは、いくらでも深くネストしうる構造を持っています。

const obj = {
    "one": 1,
    "two": {
        "three": 3
    },
    "four": {
        "five": 5,
        "six": {
            "seven": 7
        },
        "eight": 8
    },
    "nine": 9
};

ここで必要になるのは、このようなネストされたJSONオブジェクトを1つ受け取り、ネストを一切含まない新しいオブジェクトを返すJavaScript関数です。元々ネストしていたキーは、ドット記法を使って親キーと連結し、対応する値をマッピングします。

上記のオブジェクトの場合、期待される出力は次のとおりです。

const output = {
    'one': 1,
    'two.three': 3,
    'four.five': 5,
    'four.six.seven': 7,
    'four.eight': 8,
    'nine': 9
};

実装例

この処理を実現するコードは以下のとおりです。再帰呼び出しを利用することで、ネストの深さがいくらでも対応できるのがポイントです。

const obj = {
    "one": 1,
    "two": {
        "three": 3
    },
    "four": {
        "five": 5,
        "six": {
            "seven": 7
        },
        "eight": 8
    },
    "nine": 9
};
const flattenJSON = (obj = {}, res = {}, extraKey = '') => {
    for(key in obj){
        if(typeof obj[key] !== 'object'){
            res[extraKey + key] = obj[key];
        }else{
            flattenJSON(obj[key], res, `${extraKey}${key}.`);
        };
    };
    return res;
};
console.log(flattenJSON(obj));

コンソール出力

このコードを実行すると、コンソールには次のように出力されます。

{
    one: 1,
    'two.three': 3,
    'four.five': 5,
    'four.six.seven': 7,
    'four.eight': 8,
    nine: 9
}

コードの仕組み

flattenJSON 関数の動作を支えているのは、主に次の3つの要素です。

  • 再帰処理: 各プロパティの値を typeof で判定し、値がオブジェクトであれば自分自身を再帰的に呼び出して、より深い階層へ潜っていきます。
  • extraKey 引数: 親キーの情報を "four.six." のように末尾にドットを付けて蓄積しながら下位の呼び出しへ渡すことで、"four.six.seven" のような完全なキー名を組み立てます。
  • デフォルト引数: obj = {}res = {}extraKey = '' をデフォルト値として設定しているため、最初の呼び出し時には対象オブジェクトを渡すだけで済みます。また、結果を格納する res を引数で共有することで、再帰全体で1つの結果オブジェクトを使い回しています。

利用時の注意点

実務で使う際は、いくつか留意しておきたい点があります。typeof null === 'object' となるため、値に null が含まれる可能性がある場合は事前にチェックを入れると安全です。また、配列が含まれるオブジェクトに対しては、インデックスがキー名に反映され(例:'items.0.name')、そのまま文字列結合されます。必要に応じて、これらのケースへの対処を追加すると、より堅牢なフラット化関数になります。

  1. JavaScriptのRegExp(正規表現)オブジェクトとは?基本の使い方をわかりやすく解説

    RegExp(正規表現)オブジェクトは、テキストに対してパターンマッチングを行い、目的の文字列部分を検索・抽出するために使用されます。JavaScriptでは、RegExpオブジェクトを「RegExpコンストラクタ」または「リテラル構文」の2通りの方法で作成できます。 RegExpオブジェクトの作成方法 コンストラクタを使用する場合: new RegExp(pattern) リテラル構文を使用する場合: /pattern/ 主なメソッド test():文字列がパターンに一致するかどうかを真偽値(true / false)で返します。 exec():パターンに一致した文字列を返します。

  2. JavaScriptのオブジェクト初期化子とは?使い方をサンプルコードで解説

    オブジェクト初期化子とは オブジェクト初期化子(Object Initializer)は、新しく生成したオブジェクトを初期化するための式です。波括弧 {} の中に、「プロパティ名」と「それに対応する値」のペアを0個以上、カンマ区切りで列挙して記述します。 これにより、変数宣言と同時にオブジェクトの中身を簡単に定義することができます。 以下は、JavaScriptでオブジェクト初期化子を使用したサンプルコードです。 サンプルコード <!DOCTYPE html> <html lang="en"> <head> <meta chars