Posted at

連想配列(辞書オブジェクト)n個の共通配列を上書きなしで結合マージする

同じ構造を持ったカテゴリごとに分割したオブジェクトを利用時には結合してひとつのオブジェクトとして扱いたい。

Object.assignは同プロパティは上書きなので、これを結合に変えたい。

各値は配列として持っていて、これを結合した配列にしたい。

結局泥臭く2重ループで、どちらかといえば配列処理。

やりたかったことの割りに何の変哲もない初歩処理になってしまった…


コード

const template = ['dog', 'cat', 'human']

const hira = {
'dog': ['いぬ'],
'cat': ['ねこ'],
'human': ['ひと'],
}

const kana = {
'dog': ['イヌ'],
'cat': ['ネコ', 'ニャンコ'],
}

const kan = {
'dog': [],
'cat': [''],
'human': [''],
'car' : [''],
}

hira kana kanを指定したプロパティのみで結合したオブジェクトにしたい。

また、渡すオブジェクトは任意個としたい。


期待する出力

{

'dog': ['いぬ', 'イヌ'],
'cat': ['ねこ', 'ネコ', 'ニャンコ', ''],
'human': ['ひと', '']
}

キー指定なのはどの配列が全部のプロパティを持っているかが不明なので?

どれかをObject.keys()しても良いし、全部上書き結合してからObject.keys()すれば全てのプロパティは取得できるはず。

なので内部で作っても良いが、私が暗黙的に理解しているという前提で今は直接指定してやる。

function merge(names, ...dics) {

const newObj = {}
names.forEach(name => {
newObj[name] = []
dics.forEach(dic => {
if (dic.hasOwnProperty(name)) {
newObj[name] = newObj[name].concat(dic[name])
}
})
})
return newObj
}
console.log(merge(template, hira, kana, kan, {}))

できれば一括で各オブジェクトからあるプロパティの値を引っ張りたかったが、いい方法は浮かばなかったので一個一個取る。

配列チェックやユニーク化、再帰化は必要になったら。

可変長引数はやっぱり便利。


他の配列操作系