JavaScriptで配列内のオブジェクトを特定のプロパティでグループ化し、重複データを結合する方法
例えば、データストレージデバイスに関する情報を格納した、次のようなオブジェクトの配列があるとします。
const drives = [
{size:"900GB", count:3},
{size:"900GB", count:100},
{size:"1200GB", count:5},
{size:"900GB", count:1}
];このデータを見ると、「900GB」という同じサイズが複数回登場しています。
ここで求められているのは、このような配列を受け取り、重複しているサイズを1つの要素にまとめ、その際にそれぞれの count(個数) を合計する関数を作成することです。
実装例
以下のコードでは、reduce() を使って size をキーとしたマップ(連想オブジェクト)を構築し、同じサイズが既に存在する場合は count を加算、存在しない場合は新しいエントリとして登録しています。
const drives = [
{size:"900GB", count:3},
{size:"900GB", count:100},
{size:"1200GB", count:5},
{size:"900GB", count:1}
];
const groupDrives = (arr = []) => {
// size をキーとして各オブジェクトを集約
const map = arr.reduce((map, e) => {
if (e.size in map) {
map[e.size].count += e.count;
} else {
map[e.size] = e;
}
return map;
}, {});
// マップのキーをもとに、元のオブジェクトを配列として再構築
const result = Object.keys(map).map(function (k) {
return this[k];
}, map);
return result;
};
console.log(groupDrives(drives));コードのポイント
- reduce() による集約: 初期値として空のオブジェクト
{}を渡し、各要素を順番に処理します。e.size in mapで同じサイズのキーが既に存在するかどうかを判定できます。 - count の合算: 同じサイズが見つかった場合は、既存エントリの
countに現在の値を足し合わせます。 - 配列への復元: 最後に
Object.keys(map)でキーの一覧を取得し、map()の第2引数にthisとしてマップ自身を渡すことで、集約後のオブジェクトを配列形式に戻しています。
なお、関数内部では引数 arr を参照するようにすることで、任意の配列に対して汎用的に動作する実装になります。
出力結果
コンソールには次のように出力されます。
[ { size: '900GB', count: 104 }, { size: '1200GB', count: 5 } ]このように、3つの「900GB」エントリ(3 + 100 + 1 = 104)が1つにまとめられ、重複のないきれいな配列が得られました。同様の手法は、売上データの商品別集計やログデータの集約など、さまざまな場面で応用できます。
-
JavaScriptでオブジェクトの配列を組み合わせる方法|reduce()によるデータ変換テクニック
はじめに本記事では、JavaScriptを使って「オブジェクトの配列」を、プロパティ(キー)ごとに値をまとめた1つのオブジェクトへ変換する方法を解説します。APIレスポンスやフォームデータの整形など、日常的な開発で役立つテクニックです。問題設定例として、学生のデータを格納した次のようなオブジェクトの配列があるとします。const arr = [{ name: 'A', idNo: 1, marks: { math: 98, sc
-
JavaScriptで配列内の定義済み要素だけを数える方法
JavaScriptでは、配列に含まれる要素を数える際、undefined のような未定義の値が混在していることがあります。このような配列から、実際に値が定義されている要素のみを正確にカウントする関数を作成する方法を解説します。問題の概要要素の配列を受け取るJavaScript関数を作成する必要があります。この配列には、いくつかの undefined 値が含まれている可能性があります。作成する関数は、配列の長さをカウントしますが、そのカウントには定義済みの要素のみを含める必要があります。解決策:filterメソッドを使った実装Array.prototype.filter() メソッドを使用する