かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript 配列をオブジェクトに変換したい。

[{id:1, ...}, {id:2, ...}. {id:3, ...}, ...] みたいな配列を{id: {...}, id: {...}, id: {...}, ...} なオブジェクトに形式に変換したい時のメモ。

e. g.

元の配列

const arg = [
  {id: 1, name: '星宮いちご', type: 'cute'},
  {id: 2, name: '霧矢あおい', type: 'cool'},
  {id: 3, name: '紫吹蘭', type: 'sexy'},
];

👇こう変換したい

{
 '1': { id: 1, name: '星宮いちご', type: 'cute' },
 '2': { id: 2, name: '霧矢あおい', type: 'cool' },
 '3': { id: 3, name: '紫吹蘭', type: 'sexy' },
}

for

const obj = {};
for(let i = 0, l = arg.length; i < l; i += 1) {
  const data = arg[i];
  obj[data.id] = data;
}

Array.forEach

const obj = {}
arg.forEach((data, i) => {
  obj[data.id] = data;
});

Array.reduce

初期値に空オブジェクト{}を渡して、それにデータを追加していけばオブジェクトに変換できます。

const obj = arg.reduce((obj, data) => {
  obj[data.id] = data;
  return obj;
}, {});

Array.reduce を使ってもっと短く書く

const obj = arg.reduce((obj, data) => ({...obj, [data.id]: data}), {});

{...obj}obj をコピーして、{[data.id]: data} はオブジェクトのキーを変数で指定して追加しています。 そしてアロー関数で return を省略してオブジェクトを返す際は、返すオブジェクトを括弧 () で囲う必要があるので ({...obj, [data:id]:id}) という形になっています。

ポエム

json-server や Firebase の Cloud Firestore からデータを取得した時とかこんな感じの配列な事が多いイメージです。変更の度に全件データを取得してDOMを更新するのはチョットイケてない感があるので delete や update しやすくするために id で対象のデータを触れるオブジェクト形式に変更したい。みたいなケースがあったので色々ためしてみました。

Array.reduce してオブジェクトをスプレッド演算子でコピーして、 ってパターンは短く書けてイケてる感があるといえばあるのですが、 Hack っぽいし都度オブジェクトをコピーしてる分パフォーマンスは良くなさそうという印象です。
ブラウザで実行されるアプリなら JavaScript はCOOLな書き方より、泥臭くても可読性が良くてパフォーマンスが良い書き方の方が「正義」なんじゃないかな〜と思ってます。


[参考]

ヘヴィーオブジェクト (電撃文庫)

ヘヴィーオブジェクト (電撃文庫)