javascript - Convert Array to Object - Stack Overflowのreduceを使った配列のオブジェクト変換が良さげだったのでメモです。
reduceについてはArray.prototype.reduce() - JavaScript | MDNあたりを。アキュムレータと各配列要素を順番に処理していくかなり便利なメソッドなのですが、初期値を空のオブジェクトに指定して各要素をオブジェクトに追加していくことでオブジェクトに変換できます。
プリミティブを要素に持つごく普通の配列の変換です。オブジェクトに変換する場合は任意のkeyを設定する必要があります。下記の例だとreduce
からindex
を受け取っています。
const arr = ['a', 'b', 'c'];
const obj = arr.reduce((result, current, index) => {
result[index] = current;
return result;
}, {});
console.log(obj); // { '0': 'a', '1': 'b', '2': 'c' }
reduceはcallbackのあとに初期値を指定することができます。冒頭に書いたように初期値を空のオブジェクト{}
にしているのがミソで、これを指定しないと初期値は最初の要素の文字列a
になってしまうのでうまく動きません。
jsonを扱うときによく見かける要素がオブジェクトになっている配列です。[{1: 'a'}, {2: 'b'}, {3: 'c'}]
のように各オブジェクトのキーをそのまま使いたい場合はObject.keys
でオブジェクトのキーの配列が戻ってくるのでこれを利用できます。下の例では返り値である配列のままキー指定をしていますが文字列に変換可能なものは変換されるため、今回は期待どおりに動作します。(参考: JavaScriptのオブジェクトのキーに配列が使える - Qiita)
const arr = [{1: 'a'}, {2: 'b'}, {3: 'c'}];
const obj = arr.reduce((result, current) => {
let key = Object.keys(current);
result[key] = current[key];
return result;
}, {});
console.log(obj); // { '1': 'a', '2': 'b', '3': 'c' }
APIを叩いて返ってきたjsonのように各オブジェクトが規則的に複数のプロパティを持っている場合は、idなどの一意のプロパティを変換後のオブジェクトのキーにしたい場面が多そうです。下は16歳以上のメンバーだけをfilter
で抽出した配列に対してメンバーの名前をキーにしたオブジェクトに変換する例です。
const arr = [{
name: 'Kotori',
age: 16,
unit: 'Printemps'
}, {
name: 'Nozomi',
age: 17,
unit: 'lily_white'
}, {
name: 'Maki',
age: 15,
unit: 'BiBi'
}];
const obj = arr
.filter(member => member.age >= 16)
.reduce((result, current) => {
result[current.name] = {
age: current.age,
unit: current.unit
}
return result;
}, {});
console.log(obj);
/*
{{ Kotori: { age: 16, unit: 'Printemps' },
Nozomi: { age: 17, unit: 'lily_white' } }
*/
forループを回すよりも見やすいのもありますが、上のようにfilter
やmap
といった配列の便利なメソッドと組み合わせやすいところが大きなメリットだと思います。