LoginSignup
0
0

More than 3 years have passed since last update.

【JavaScript】ディープマージを自前実装してみた

Posted at

先に実行結果を。

// 元データ
const test1 = {
  a: { aa: 1, ab: 2, ac: [31, 32, 33], },
  b: { ba: 4, bb: [51, 52, 53], bc: 6, },
  c: { ca: [71, 72, 73], cb: 8, cc: 9, },
}

// 差分
const test2 = {
  a: { ab: 20, ac: [], },
  b: { ba: 40, bb: [51], },
  c: { ca: [71, 72, 73, 74, 75], cc: '9' },
  d: { da: ['a', 'b', 'c'], db: 'd', dc: 'e', },
}

// マージ結果
deepMerge(test1, test2);
{
  a: { aa: 1, ab: 20, ac: [] },
  b: { ba: 40, bb: [ 51 ], bc: 6 },
  c: { ca: [ 71, 72, 73, 74, 75 ], cb: 8, cc: '9' },
  d: { da: [ 'a', 'b', 'c' ], db: 'd', dc: 'e' }
}

実装はこんな感じ。

// メインの関数
const deepMerge = (base, difference) => {
  const merged = JSON.parse(JSON.stringify(base));
  const diff = JSON.parse(JSON.stringify(difference));
  merger(merged, diff);
  return merged;
}

// これが再帰的に呼び出される
const merger = (merged, diff) => {
  for (const key of Object.keys(diff)) {
    if (!(key in merged)) {
      // パラメータの追加
      merged[key] = diff[key];
      continue;
    }
    if (typeof diff[key] === 'object' && diff[key] !== null) {
      // 配列の場合は要素数を合わせる
      if (Array.isArray(diff[key])) {
        merged[key] = merged[key].slice(0, diff[key].length)
      }
      // オブジェクトの場合は再帰呼び出し
      merger(merged[key], diff[key]);
    } else {
      // パラメータの更新
      merged[key] = diff[key];
    }
  }
}

あとがき

うーん、後から考えてみれば別に作る必要なかったかも。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0