JavaScript Tips | 配列ユーティリティ:配列正規化

JavaScript JavaScript
スポンサーリンク

テーマの整理:「配列正規化」とは何か

ここでの「配列正規化」は、バラバラな形・揺れのある配列データを、「扱いやすい一定の形」にそろえるユーティリティのことです。 業務だと、次のような場面でよく出てきます。

  • API から来るデータが「配列のときもあれば単体オブジェクトのときもある」。
  • 数値が文字列 "123" で入っていたり、本当の数値 123 で入っていたりする。
  • null や undefined が混ざっていて、そのままだと処理しづらい。

こういう「揺れ」を、事前に“正規化”しておくことで、後続の処理をシンプルにするのが配列正規化です。

基本コンセプト:「何が来ても、最終的には“こういう配列”にそろえる」

よくある“揺れたデータ”の例

例えば、こんな API レスポンスがあるとします。

// パターンA: 配列で返ってくる
const responseA = [
  { id: 1, amount: "100" },
  { id: 2, amount: "200" },
];

// パターンB: 単体オブジェクトで返ってくる
const responseB = { id: 1, amount: "100" };

// パターンC: null が返ってくる
const responseC = null;
JavaScript

でも、こちら側の処理としては、

  • 「常に配列として扱いたい」
  • 「amount は数値として扱いたい」
  • 「null や変な値は無視したい」

という気持ちがあります。

そこで、「配列正規化ユーティリティ」を通して、 “どんな入力でも、最終的には同じ形の配列にしてから処理する”という方針を取ります。

ユーティリティ 1:入力を「必ず配列」に正規化する

実装:toArray

まずは、「配列かどうか分からないものを、必ず配列にする」ためのユーティリティです。

function toArray(value) {
  if (value == null) {
    return [];
  }

  if (Array.isArray(value)) {
    return value;
  }

  return [value];
}
JavaScript

重要ポイントをかみ砕いて説明

value == null は、nullundefined の両方をまとめて扱う書き方です。 null や undefined が来たときは、「要素なし」とみなして空配列 [] を返します。

Array.isArray(value) で「すでに配列かどうか」を判定します。 配列ならそのまま返します(余計なコピーはしない)。

それ以外(オブジェクト・数値・文字列など)の場合は、「単体の値」とみなして、 [value] のように「1 要素の配列」に包みます。

これで、

  • 配列が来ても、
  • 単体オブジェクトが来ても、
  • null が来ても、

必ず「配列」として扱えるようになるわけです。

例題 1:API レスポンスを「必ず配列」に正規化する

const responseA = [
  { id: 1, amount: "100" },
  { id: 2, amount: "200" },
];

const responseB = { id: 1, amount: "100" };

const responseC = null;

console.log(toArray(responseA)); // そのまま配列
console.log(toArray(responseB)); // [{ id: 1, amount: "100" }]
console.log(toArray(responseC)); // []
JavaScript

ここでのポイントは、 後続の処理では「とにかく配列として扱えばいい」という前提で書けるようになることです。

例えば、こう書けます。

const items = toArray(responseFromApi);

items.forEach((item) => {
  // ここは「必ず配列」として書ける
});
JavaScript

「配列かもしれないし、単体かもしれないし、null かもしれない」という分岐を、 毎回書かなくてよくなるのが、かなり大きなメリットです。

ユーティリティ 2:配列の中身を「型・値の揺れ」をそろえて正規化する

シナリオ

次のような配列があるとします。

const raw = [
  { id: "1", amount: "100", active: "true" },
  { id: 2,   amount: 200,   active: true },
  { id: "3", amount: null,  active: "false" },
];
JavaScript

ここから、

  • id は数値にしたい。
  • amount は数値にしたい(null や変な値は 0 にしたい)。
  • active は真偽値にしたい。

という「正規化ルール」を決めておきます。

実装:normalizeRecords

function normalizeRecords(records) {
  const array = toArray(records);

  return array
    .filter((r) => r != null)
    .map((r) => ({
      id: Number(r.id),
      amount: r.amount == null ? 0 : Number(r.amount),
      active: r.active === true || r.active === "true",
    }));
}
JavaScript

重要ポイントをかみ砕いて説明

まず toArray(records) で「必ず配列」にしています。 そのあと filter((r) => r != null) で、null や undefined の要素を取り除いています。

id: Number(r.id) で、「文字列でも数値でも、とにかく数値に変換」しています。 amount は、null や undefined のときは 0 にして、それ以外は Number で数値にしています。 active は、「真偽値 true」か「文字列 ‘true’」なら true、それ以外は false にしています。

こうすることで、 「どんな揺れた入力が来ても、最終的には同じ型・同じルールの配列になる」わけです。

例題 2:揺れたレコード配列を正規化する

const raw = [
  { id: "1", amount: "100", active: "true" },
  { id: 2,   amount: 200,   active: true },
  { id: "3", amount: null,  active: "false" },
];

const normalized = normalizeRecords(raw);

console.log(normalized);
JavaScript

出力イメージはこうなります。

[
  { id: 1, amount: 100, active: true },
  { id: 2, amount: 200, active: true },
  { id: 3, amount: 0,   active: false },
]
JavaScript

ここでのポイントは、

  • id が全部数値になっている。
  • amount が全部数値になっていて、null は 0 に置き換えられている。
  • active が全部真偽値になっている。

というところです。

この「正規化された配列」を前提にすると、 後続の処理(集計・フィルタ・ソートなど)がかなり書きやすくなります。

ユーティリティ 3:配列の「空・null・重複」をそろえる正規化

シナリオ

次のような配列があるとします。

const rawIds = [1, null, 2, undefined, 2, 3, 3];
JavaScript

ここから、

  • null や undefined は捨てたい。
  • 重複は取り除いて、ユニークな ID だけにしたい。

という「正規化」をしたいとします。

実装:normalizeIdList

function normalizeIdList(ids) {
  const array = toArray(ids);

  const filtered = array.filter((id) => id != null);

  const unique = Array.from(new Set(filtered));

  return unique;
}
JavaScript

重要ポイントをかみ砕いて説明

toArray(ids) で「必ず配列」にしています(単体の ID が来ても対応できる)。 filter((id) => id != null) で、null と undefined を取り除いています。 new Set(filtered) で重複を排除し、Array.from で配列に戻しています。

これで、「空・null・重複の揺れ」をそろえた ID 配列が手に入ります。

例題 3:ID 配列を正規化する

const rawIds = [1, null, 2, undefined, 2, 3, 3];

const normalizedIds = normalizeIdList(rawIds);

console.log(normalizedIds);
JavaScript

出力イメージはこうなります。

[1, 2, 3]
JavaScript

この「正規化された ID 配列」を使えば、 後続の処理で「null チェック」「重複チェック」を毎回書かなくて済みます。

配列正規化ユーティリティで意識してほしい重要ポイント

「後続の処理を楽にするための前処理」として考える

配列正規化は、それ自体が目的ではなく、「後続の処理をシンプルにするための前処理」です。

  • ここで「配列にそろえる」から、後ろでは forEachmap を安心して使える。
  • ここで「型をそろえる」から、後ろでは NumberBoolean の変換を意識しなくて済む。
  • ここで「null や重複を処理する」から、後ろでは「きれいな配列」として扱える。

初心者のうちは、

「この処理の前に、どんな正規化をしておくと楽になるか?」

という視点で考えると、 配列正規化ユーティリティの設計がしやすくなります。

「入力の揺れ」をちゃんと想像する

実務では、入力はだいたい「きれいではない」です。

  • API の仕様が微妙に変わる。
  • 人間が手入力したデータが混ざる。
  • 古いデータと新しいデータが混在する。

だからこそ、

  • null が来るかもしれない。
  • 配列じゃなくて単体が来るかもしれない。
  • 数値が文字列で来るかもしれない。

という「揺れ」を想像して、 それを受け止める正規化ユーティリティを用意しておくと、 コード全体の安定感がぐっと増します。

手を動かして「配列正規化」の感覚をつかむ

次のコードを実行して、

  • toArray で「必ず配列」にする。
  • normalizeRecords で「型・値の揺れ」をそろえる。
  • normalizeIdList で「null・重複」をそろえる。

という流れを体感してみてください。

function toArray(value) {
  if (value == null) {
    return [];
  }

  if (Array.isArray(value)) {
    return value;
  }

  return [value];
}

function normalizeRecords(records) {
  const array = toArray(records);

  return array
    .filter((r) => r != null)
    .map((r) => ({
      id: Number(r.id),
      amount: r.amount == null ? 0 : Number(r.amount),
      active: r.active === true || r.active === "true",
    }));
}

function normalizeIdList(ids) {
  const array = toArray(ids);
  const filtered = array.filter((id) => id != null);
  const unique = Array.from(new Set(filtered));
  return unique;
}

function demo() {
  const responseA = [
    { id: "1", amount: "100", active: "true" },
    { id: 2,   amount: 200,   active: true },
  ];

  const responseB = { id: "3", amount: null, active: "false" };

  const normalizedA = normalizeRecords(responseA);
  const normalizedB = normalizeRecords(responseB);

  console.log("=== normalizedA ===");
  console.log(normalizedA);

  console.log("=== normalizedB ===");
  console.log(normalizedB);

  const rawIds = [1, null, 2, undefined, 2, 3, 3];
  console.log("=== normalizeIdList ===");
  console.log(normalizeIdList(rawIds));
}

demo();
JavaScript

まとめ:配列正規化ユーティリティで「揺れた現実を、扱いやすい形にそろえる」

配列正規化は、 「現実世界の“揺れたデータ”を、コードが扱いやすい“きれいな配列”にそろえるためのユーティリティ」です。

プロジェクトに例えば次のような形で置いておくイメージです。

export function toArray(value) { ... }
export function normalizeRecords(records) { ... }
export function normalizeIdList(ids) { ... }
JavaScript

そして、

  • API 受信直後
  • DB からの読み出し直後
  • 人間入力データを受け取った直後

など、「揺れたデータが入ってくる入口」で必ずこの正規化を通す。

こう決めておくと、 後ろ側の処理は「きれいな配列」を前提に書けるようになり、 コードが一気に読みやすく・壊れにくくなります。

配列正規化は、地味だけど“現場感”のあるテクニックです。 ここを押さえておくと、「実務で戦えるコード」にぐっと近づきます。

タイトルとURLをコピーしました