JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptでオブジェクトの配列を組み合わせる方法|reduce()によるデータ変換テクニック

はじめに

本記事では、JavaScriptを使って「オブジェクトの配列」を、プロパティ(キー)ごとに値をまとめた1つのオブジェクトへ変換する方法を解説します。APIレスポンスやフォームデータの整形など、日常的な開発で役立つテクニックです。

問題設定

例として、学生のデータを格納した次のようなオブジェクトの配列があるとします。

const arr = [{
   name: 'A',
   idNo: 1,
   marks: {
      math: 98,
      sci: 97,
      eng: 89
   }
},
{
   name: 'B',
   idNo: 2,
   marks: {
      math: 88,
      sci: 87,
      eng: 79
   }
},
{
   name: 'C',
   idNo: 3,
   marks: {
      math: 87,
      sci: 98,
      eng: 91
   }
}];

ここで求められているのは、このような配列を引数として受け取り、元の各オブジェクトが持っているプロパティごとに値を集約した新しいオブジェクトを返す関数を作成することです。

そのため、上記の配列の場合、期待される出力は次のようになります。

const output = {
   name: ['A', 'B', 'C'],
   idNo: [1, 2, 3],
   marks: [{
      math: 98,
      sci: 97,
      eng: 89
   },
   {
      math: 88,
      sci: 87,
      eng: 79
   },
   {
      math: 87,
      sci: 98,
      eng: 91
   }]
};

つまり、「縦持ち」のレコード形式(配列)から、「横持ち」のカラム形式(オブジェクト)への変換を行うイメージです。

実装例

実際のコードは以下の通りです。

const arr = [{
   name: 'A',
   idNo: 1,
   marks: {
      math: 98,
      sci: 97,
      eng: 89
   }
},
{
   name: 'B',
   idNo: 2,
   marks: {
      math: 88,
      sci: 87,
      eng: 79
   }
},
{
   name: 'C',
   idNo: 3,
   marks: {
      math: 87,
      sci: 98,
      eng: 91
   }
}];
const combineMarks = (arr = []) => {
   let res = [];
   res = arr.reduce((acc, val) => {
      Object.keys(val).forEach(el => {
         if (!acc[el]) {
            acc[el] = [];
         };
         acc[el].push(val[el])
      });
      return acc;
   }, {});
   return res;
};
console.log(combineMarks(arr));

実行結果

コンソールには次のように出力されます。

{
   name: [ 'A', 'B', 'C' ],
   idNo: [ 1, 2, 3 ],
   marks: [
      { math: 98, sci: 97, eng: 89 },
      { math: 88, sci: 87, eng: 79 },
      { math: 87, sci: 98, eng: 91 }
   ]
}

コードの解説

この実装の核となるのはArray.prototype.reduce()メソッドです。処理の流れは以下の通りです。

  1. reduce()の初期値として空のオブジェクト{}を渡します。
  2. 配列の各要素(オブジェクト)に対して、Object.keys()でそのオブジェクトが持つキーの一覧を取得します。
  3. 各キーについて、累積オブジェクトaccに該当キーがまだ存在しない場合は、空の配列で初期化します。
  4. その配列へ現在の値をpush()していきます。

これにより、ループが完了した時点で、すべてのオブジェクトの値が「name」「idNo」「marks」といったプロパティごとの配列に整理されます。

補足:柔軟性について

この手法は、各オブジェクトが異なるキーを持っている場合にも対応できます。Object.keys()は各オブジェクトに実際に存在するキーだけを処理するため、一部のオブジェクトでプロパティが欠けていてもエラーにならず、存在する値のみが収集されます。また、ネストされたオブジェクト(ここではmarks)も参照渡しでそのまま配列に格納されるため、深い構造のデータもそのまま扱える点が便利です。

  1. JavaScriptのオブジェクト配列に配列メソッドを適用する方法

    JavaScriptでは、オブジェクトが格納された配列に対しても、通常の配列と同じようにpop()、push()、splice()などの標準的な配列メソッドをそのまま使用できます。オブジェクト配列はあくまで「配列」であるため、要素としてオブジェクトが入っていても配列操作のAPIは共通で動作します。 コード例 以下は、JavaScriptオブジェクトの配列に対して配列メソッドを使用するサンプルコードです。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8

  2. JavaScriptでフラットなオブジェクト配列をツリー構造に変換する方法

    はじめにWeb開発では、カテゴリ一覧やフォルダ構成、組織図など、階層構造をもつデータを画面に表示したい場面がよくあります。一方で、データベースやAPIから取得したデータは、idとparentIdを持つフラット(一次元)な配列として渡されることがほとんどです。本記事では、こうしたフラットな配列をもとに、子要素を親オブジェクトへリンクさせたツリー構造を組み立て、ネストされたリスト形式で画面に表示するまでの手順を、HTML・CSSのコード付きでわかりやすく解説します。元データとなるフラットな配列まず、変換対象となるデータを確認しましょう。各オブジェクトは、自身の一意な識別子であるid、表示名のnam