テーマの整理:「サマリー生成」とは何か
ここでの「サマリー生成」は、配列に入っているたくさんのデータを「要約・集計」して、業務で使いやすい形にまとめるユーティリティのことです。 「生データの配列」から、次のような情報を取り出すイメージです。
- 合計・平均・最大値・最小値
- 件数(全体件数・条件に合う件数)
- カテゴリごとの集計(店舗別、担当者別、ステータス別など)
ポイントは、「1 件ずつ眺める」のではなく、“配列全体を見て、要約情報を作る”ことです。
基本コンセプト:「生データ配列」から「サマリーオブジェクト」を作る
どんなデータからサマリーを作るのか
よくある形は、こんな売上データの配列です。
const sales = [
{ id: 1, store: "A", amount: 100, taxIncluded: true },
{ id: 2, store: "A", amount: 200, taxIncluded: false },
{ id: 3, store: "B", amount: 150, taxIncluded: true },
];
JavaScriptここから、例えば次のようなサマリーを作りたくなります。
- 全体の売上合計
- 全体の平均金額
- 店舗ごとの売上合計
- 税込み・税抜きの件数
こういう「要約情報」を、配列から自動で生成するユーティリティがあると、 画面表示・レポート・ログ出力などでとても便利です。
ユーティリティ 1:基本的な数値サマリー(合計・平均・最大・最小)
実装:numericSummary
まずは、数値配列に対して「基本的なサマリー」を作るユーティリティです。
function numericSummary(values) {
if (!Array.isArray(values) || values.length === 0) {
return {
count: 0,
sum: 0,
avg: 0,
min: null,
max: null,
};
}
let sum = 0;
let min = Number.POSITIVE_INFINITY;
let max = Number.NEGATIVE_INFINITY;
let count = 0;
values.forEach((v) => {
if (typeof v !== "number" || Number.isNaN(v)) {
return;
}
sum += v;
count += 1;
if (v < min) min = v;
if (v > max) max = v;
});
const avg = count === 0 ? 0 : sum / count;
if (count === 0) {
return {
count: 0,
sum: 0,
avg: 0,
min: null,
max: null,
};
}
return {
count,
sum,
avg,
min,
max,
};
}
JavaScript重要ポイントをかみ砕いて説明
values が配列でない・空配列のときは、「全部 0・min/max は null」というサマリーを返します。 sum・min・max・count を自分で管理しながら、forEach で数値だけを集計しています。 数値でないものや NaN は無視しています(業務データには変な値が混ざることがあるので)。 平均 avg は「count が 0 のときは 0」「それ以外は sum / count」で計算しています。
これで、「数値配列の基本的なサマリー」が一発で手に入ります。
例題 1:売上金額のサマリーを作る
const amounts = [100, 200, 150];
const summary = numericSummary(amounts);
console.log(summary);
JavaScript出力イメージはこうなります。
{
count: 3,
sum: 450,
avg: 150,
min: 100,
max: 200
}
JavaScriptここでのポイントは、「配列を見なくても、サマリーだけで全体のイメージがつかめる」ことです。 画面の上部に「合計」「平均」「最大」「最小」を出すときなどに、そのまま使えます。
ユーティリティ 2:オブジェクト配列から「特定フィールドのサマリー」を作る
シナリオ
売上配列から「amount のサマリー」を作りたい。 ユーザー配列から「age のサマリー」を作りたい。
実装:fieldNumericSummary
function fieldNumericSummary(records, field) {
if (!Array.isArray(records) || records.length === 0) {
return numericSummary([]);
}
const values = records
.map((r) => r[field])
.filter((v) => typeof v === "number" && !Number.isNaN(v));
return numericSummary(values);
}
JavaScript重要ポイントをかみ砕いて説明
records が配列でない・空配列なら、numericSummary([]) を返します。 指定フィールド field の値だけを取り出し、数値でないものや NaN をフィルタしています。 最後は numericSummary に渡して、基本サマリーを作っています。
これで、「オブジェクト配列の特定フィールドに対するサマリー」が簡単に作れます。
例題 2:売上配列から amount のサマリーを作る
const sales = [
{ id: 1, store: "A", amount: 100 },
{ id: 2, store: "A", amount: 200 },
{ id: 3, store: "B", amount: 150 },
];
const amountSummary = fieldNumericSummary(sales, "amount");
console.log(amountSummary);
JavaScript出力イメージはこうなります。
{
count: 3,
sum: 450,
avg: 150,
min: 100,
max: 200
}
JavaScriptこの形は、ダッシュボードやレポートの「総売上」「平均単価」などにそのまま使えます。
ユーティリティ 3:カテゴリごとのサマリー(グルーピング+集計)
シナリオ
店舗ごとの売上サマリーを作りたい。 ステータスごとの件数・合計を出したい。
実装:groupSummary
まず、「グループキーごとに数値フィールドを集計する」ユーティリティを作ります。
function groupSummary(records, groupField, valueField) {
if (!Array.isArray(records) || records.length === 0) {
return {};
}
const groups = new Map();
records.forEach((r) => {
const key = r[groupField];
const value = r[valueField];
if (typeof value !== "number" || Number.isNaN(value)) {
return;
}
if (!groups.has(key)) {
groups.set(key, []);
}
groups.get(key).push(value);
});
const result = {};
groups.forEach((values, key) => {
result[key] = numericSummary(values);
});
return result;
}
JavaScript重要ポイントをかみ砕いて説明
groupField(例: “store”)でグループキーを取り出し、valueField(例: “amount”)で数値を取り出します。 Map を使って「グループキー → 数値配列」の対応を作っています。 最後に、各グループの数値配列に対して numericSummary を適用し、 結果を普通のオブジェクト { storeA: {...}, storeB: {...} } にまとめています。
これで、「カテゴリごとのサマリー」が一発で作れます。
例題 3:店舗ごとの売上サマリーを作る
const sales = [
{ id: 1, store: "A", amount: 100 },
{ id: 2, store: "A", amount: 200 },
{ id: 3, store: "B", amount: 150 },
];
const storeSummary = groupSummary(sales, "store", "amount");
console.log(JSON.stringify(storeSummary, null, 2));
JavaScript出力イメージはこうなります。
{
"A": {
"count": 2,
"sum": 300,
"avg": 150,
"min": 100,
"max": 200
},
"B": {
"count": 1,
"sum": 150,
"avg": 150,
"min": 150,
"max": 150
}
}
JavaScriptここでのポイントは、
- 店舗 A のサマリー
- 店舗 B のサマリー
がそれぞれまとまっていることです。
この形は、画面で「店舗別の集計表」を出したり、 レポートで「店舗別の売上サマリー」を載せたりするときに、そのまま使えます。
ユーティリティ 4:件数サマリー(条件ごとのカウント)
シナリオ
「active なユーザーの件数」「inactive なユーザーの件数」を知りたい。 「税込み」「税抜き」の件数を知りたい。
実装:countBy
function countBy(records, field) {
if (!Array.isArray(records) || records.length === 0) {
return {};
}
const result = {};
records.forEach((r) => {
const key = r[field];
const k = String(key);
if (!result[k]) {
result[k] = 0;
}
result[k] += 1;
});
return result;
}
JavaScript重要ポイントをかみ砕いて説明
field の値をキーとして、件数をカウントしています。 キーは文字列にしておくと、true/false や数値も扱いやすくなります。 戻り値は { "true": 10, "false": 3 } のような形になります。
例題 4:active フラグごとの件数サマリーを作る
const users = [
{ id: 1, active: true },
{ id: 2, active: false },
{ id: 3, active: true },
];
const activeSummary = countBy(users, "active");
console.log(activeSummary);
JavaScript出力イメージはこうなります。
{
"true": 2,
"false": 1
}
JavaScriptこの形は、「ステータスごとの件数」を出すときにとても便利です。
サマリー生成ユーティリティで意識してほしい重要ポイント
「生データを全部見なくても、サマリーだけで状況が分かる」状態を作る
サマリー生成の目的は、「大量の配列を全部眺めなくても、要約だけで状況が分かるようにする」ことです。
- 合計・平均・最大・最小で「全体の傾向」が分かる。
- カテゴリごとのサマリーで「どこが強いか・弱いか」が分かる。
- 件数サマリーで「どのステータスが多いか」が分かる。
初心者のうちは、
「この配列から、どんなサマリーがあると嬉しいか?」
と考えてみると、 どんなユーティリティを作るべきかが見えてきます。
「サマリーは“表示・レポート・監視”の入口になる」
サマリー生成ユーティリティは、 画面表示・レポート・監視・ログなどの「入口」によく使われます。
- ダッシュボードの上部にサマリーを表示する。
- CSV の先頭行にサマリー行を追加する。
- ログに「処理対象のサマリー」を出しておく。
こうしておくと、後から見返したときに「何が起きていたか」がすぐ分かります。
手を動かして「サマリー生成」の感覚をつかむ
次のコードを実行して、
- 数値サマリー
- フィールドサマリー
- グループサマリー
- 件数サマリー
を一気に体感してみてください。
function numericSummary(values) {
if (!Array.isArray(values) || values.length === 0) {
return { count: 0, sum: 0, avg: 0, min: null, max: null };
}
let sum = 0;
let min = Number.POSITIVE_INFINITY;
let max = Number.NEGATIVE_INFINITY;
let count = 0;
values.forEach((v) => {
if (typeof v !== "number" || Number.isNaN(v)) return;
sum += v;
count += 1;
if (v < min) min = v;
if (v > max) max = v;
});
const avg = count === 0 ? 0 : sum / count;
if (count === 0) {
return { count: 0, sum: 0, avg: 0, min: null, max: null };
}
return { count, sum, avg, min, max };
}
function fieldNumericSummary(records, field) {
if (!Array.isArray(records) || records.length === 0) {
return numericSummary([]);
}
const values = records
.map((r) => r[field])
.filter((v) => typeof v === "number" && !Number.isNaN(v));
return numericSummary(values);
}
function groupSummary(records, groupField, valueField) {
if (!Array.isArray(records) || records.length === 0) {
return {};
}
const groups = new Map();
records.forEach((r) => {
const key = r[groupField];
const value = r[valueField];
if (typeof value !== "number" || Number.isNaN(value)) return;
if (!groups.has(key)) {
groups.set(key, []);
}
groups.get(key).push(value);
});
const result = {};
groups.forEach((values, key) => {
result[key] = numericSummary(values);
});
return result;
}
function countBy(records, field) {
if (!Array.isArray(records) || records.length === 0) {
return {};
}
const result = {};
records.forEach((r) => {
const key = String(r[field]);
if (!result[key]) {
result[key] = 0;
}
result[key] += 1;
});
return result;
}
function demo() {
const sales = [
{ id: 1, store: "A", amount: 100, taxIncluded: true },
{ id: 2, store: "A", amount: 200, taxIncluded: false },
{ id: 3, store: "B", amount: 150, taxIncluded: true },
];
console.log("=== numericSummary (amounts) ===");
console.log(numericSummary(sales.map((s) => s.amount)));
console.log("=== fieldNumericSummary (amount) ===");
console.log(fieldNumericSummary(sales, "amount"));
console.log("=== groupSummary (store, amount) ===");
console.log(JSON.stringify(groupSummary(sales, "store", "amount"), null, 2));
console.log("=== countBy (taxIncluded) ===");
console.log(countBy(sales, "taxIncluded"));
}
demo();
JavaScriptまとめ:サマリー生成ユーティリティで「配列の海から、意味のある“要約”をすくい上げる」
サマリー生成は、 「大量の配列データから、業務で意味のある“要約情報”をすくい上げるためのユーティリティ」です。
プロジェクトに例えば次のような形で置いておくイメージです。
export function numericSummary(values) { ... }
export function fieldNumericSummary(records, field) { ... }
export function groupSummary(records, groupField, valueField) { ... }
export function countBy(records, field) { ... }
JavaScriptそして、
ダッシュボード表示前、 レポート生成前、 ログ出力前
など、「状況をざっくり把握したい場面」で必ずこのサマリー生成を通す。
こう決めておくと、 配列の海から「意味のある数字」だけを取り出せるようになり、 業務の判断や振り返りがぐっとやりやすくなります。
生データは“素材”、サマリーは“料理された結果”。 その料理を自動で作ってくれるのが、サマリー生成ユーティリティです。
