前提・実現したいこと
マップ的に利用するオブジェクトがネストされているようなオブジェクトが2つあり、そのマージ方法について、再帰的で汎用的な方法があるかお聞きしたいです。(言葉での説明だと分からないかと思うので、内容については「該当のソースコード」をご確認ください)
方法は非破壊的であるとよりうれしいですが、破壊的であっても良いです。
外部ライブラリも、可能な限り利用したくないです。
該当のソースコード
以下のmargeMagic()
の実装方法で悩んでいます。
javascript
1function margeMagic(a, b) { 2 // 今回の質問点 3} 4 5const data1 = { a: 10, b: 11, c: { ca: "test", cb: 5, cd: ["hoge", "hogehoge"] } }; 6const data2 = { a: 11, c: { cc: "yes", cd: ["foo", "bar"] }, d: 10 }; 7const merged = margeMagic(data1, data2); 8console.log(c) // 期待 ⇒ { a: 11, b: 11, c: {ca: "test", cb: 4, cc: "yes", cd: ["foo", "bar"] }, d: 10}
- data1 にしかキーがないプロパティはdata1 の値
- data2 にしかキーがないプロパティはdata2 の値
- 双方にキーがあるプロパティは
-- 値がマップだったらそのマップ内も上記と同様の処理
-- プリミティブや配列等であればdata2 の値(配列はマージせずそのまま)
試したこと
1. Object.assign
Object.assign
では、上記の例のmerged.c
がdata2.c
の値になってしまいます。期待としては、merged.c
もうまくマージされてほしい。(c: {ca: "test", cb: 4, cc: "yes", cd: ["foo", "bar"] }
)
2. for...inを利用
この場合、プロパティの中がさらにマップであれば同じことを繰り返すようにしたいのですが、ArrayやらFloat32Arrayやらはいちいち回したくないので普通に上書きしたい気持ちがあります。
そのため、「キーがあるかどうか」だけでは判別できません。
また、typeof hoge === "object"
の場合にキーを見に行く、とやろうとするとhoge = new Array(100)
の場合も分岐に入ってしまい回ってしまいます。
hoge instanceof Object
の場合にキーを見に行くと、ボクシングしたプリミティブ(new String("hoge")
とか。非推奨っぽくはありますが)も通ってしまい、期待通りになりません。
結局今は
特定のオリジナル型に特化したマージ関数を作っているのですが、カッコ悪いしレイアウト変わったり他にも似たようなことやるとなるとかなり面倒なことになるので、汎用的なものを作りたいのです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/05/31 08:19
退会済みユーザー
2018/05/31 09:18