JavaScript Tips | 配列ユーティリティ:カラム抽出

JavaScript JavaScript
スポンサーリンク

テーマの整理:「カラム抽出」とは何か

ここでの「カラム抽出」は、オブジェクト配列から「欲しい列だけ」を取り出すためのユーティリティです。 業務だと、次のような場面でよく使います。

画面の一覧では 10 項目あるけど、CSV には 5 項目だけ出したい。 Excel に渡すときに、特定の列順・特定の項目だけに絞りたい。 API から来たデータのうち、必要なフィールドだけを別処理に渡したい。

つまり「配列の中身を全部使う」のではなく、 “このカラムだけ欲しい”をコードで表現するのがカラム抽出です。

基本コンセプト:オブジェクト配列から「列のサブセット」を作る

どんな形のデータから抽出するのか

よくある形は、こんなオブジェクト配列です。

const users = [
  { id: 1, name: "Alice", email: "alice@example.com", active: true },
  { id: 2, name: "Bob",   email: "bob@example.com",   active: false },
];
JavaScript

ここから、例えば「id と name だけ欲しい」とします。 結果として欲しいのは、こういう配列です。

[
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
]
JavaScript

これが「カラム抽出」です。 元の配列はそのままにしておきつつ、「必要なカラムだけの配列」を新しく作ります。

ユーティリティ 1:オブジェクト配列から指定カラムだけを抽出する

実装:pickColumns

まずは、初心者でも読めるシンプルなカラム抽出ユーティリティを書きます。

function pickColumns(objects, keys) {
  if (!Array.isArray(objects) || objects.length === 0) {
    return [];
  }

  if (!Array.isArray(keys) || keys.length === 0) {
    return [];
  }

  return objects.map((obj) => {
    const picked = {};
    keys.forEach((key) => {
      picked[key] = obj[key];
    });
    return picked;
  });
}
JavaScript

ここでの重要ポイントをかみ砕いて説明します。

objects は「元のオブジェクト配列」です。 keys は「欲しいカラムのキー名の配列」です(例: ["id", "name"])。 配列でなかったり空だったりした場合は、空配列を返して処理を落とさないようにしています。 各オブジェクトについて、keys の順番に従って新しいオブジェクトを作り、そこに対応する値だけを入れています。

つまり、「元のオブジェクトをコピーする」のではなく、 “必要なキーだけを持つ新しいオブジェクト”を作っているわけです。

例題 1:ユーザー一覧から「id と name だけ」を抽出する

const users = [
  { id: 1, name: "Alice", email: "alice@example.com", active: true },
  { id: 2, name: "Bob",   email: "bob@example.com",   active: false },
];

const simpleUsers = pickColumns(users, ["id", "name"]);

console.log(simpleUsers);
JavaScript

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

[
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
]
JavaScript

ここでのポイントは、

元の users はそのまま残っている。 simpleUsers は「id と name だけ」の軽い配列になっている。

というところです。 ログ出力・CSV・Excel・別 API への送信など、「全部はいらない」場面でかなり使えます。

ユーティリティ 2:カラム抽出+列順制御(表・CSV・Excel向け)

列順も一緒に決める

CSV や Excel に出すときは、「どのカラムを」「どの順番で」出すかが重要です。 さっきの pickColumns は「キーの集合」を作るだけですが、 列順も意識したいときは、少しだけ拡張します。

function pickColumnsWithOrder(objects, keys) {
  const picked = pickColumns(objects, keys);

  return picked.map((obj) => {
    const ordered = {};
    keys.forEach((key) => {
      ordered[key] = obj[key];
    });
    return ordered;
  });
}
JavaScript

ここでのポイントは、

pickColumns で「必要なカラムだけのオブジェクト」を作ったあと、 keys の順番に従って改めてオブジェクトを組み立て直していることです。

JavaScript のオブジェクトは「キーの順番」が厳密には保証されませんが、 最近の環境では「追加した順番」で列挙されることが多いので、 この形にしておくと「列順を意識した出力」に使いやすくなります。

例題:CSV 出力前にカラム抽出+列順制御をする

const users = [
  { id: 1, name: "Alice", email: "alice@example.com", active: true },
  { id: 2, name: "Bob",   email: "bob@example.com",   active: false },
];

const keys = ["name", "email"];

const slimUsers = pickColumnsWithOrder(users, keys);

console.log(slimUsers);
JavaScript

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

[
  { name: "Alice", email: "alice@example.com" },
  { name: "Bob",   email: "bob@example.com" },
]
JavaScript

このまま toCsv(slimUsers, keys) のように渡せば、 「name, email」の順番で CSV を出せます。

ユーティリティ 3:単一カラムだけを「配列」として抽出する

シナリオ

ユーザー一覧から「id の配列だけ欲しい」。 売上データから「日付だけの配列」を作りたい。

実装:pluckColumn

function pluckColumn(objects, key) {
  if (!Array.isArray(objects) || objects.length === 0) {
    return [];
  }

  return objects.map((obj) => obj[key]);
}
JavaScript

ここでのポイントは、

戻り値が「オブジェクト配列」ではなく「値の配列」になっていることです。 例えば、pluckColumn(users, "id")[1, 2, 3, ...] のような配列を返します。

例題:ユーザー ID の配列を作る

const users = [
  { id: 1, name: "Alice", email: "alice@example.com", active: true },
  { id: 2, name: "Bob",   email: "bob@example.com",   active: false },
];

const ids = pluckColumn(users, "id");

console.log(ids);
JavaScript

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

[1, 2]
JavaScript

この形は、

ID の一覧を別処理に渡す。 Set に入れて重複チェックをする。 特定の ID 群だけをフィルタする。

など、業務ロジックでかなり使い勝手がいいです。

カラム抽出ユーティリティで意識してほしい重要ポイント

「元データを壊さない」こと

カラム抽出は、元の配列をそのまま残したまま、別の“軽い配列”を作るのが基本です。 元のオブジェクトを直接削ったり書き換えたりすると、 後で「他の処理が必要なカラムを見失う」事故につながります。

だからこそ、

常に「新しいオブジェクト」を作る({ ...obj } や新しい picked を返す)。 元の配列やオブジェクトには触らない。

というスタンスでユーティリティを書いておくのが大事です。

「どのカラムが必要か」を明示的に書く

keys の配列は、「この処理では何が必要か」を表す仕様そのものです。

["id", "name"] ["name", "email"] ["date", "total"]

こうやって「必要なカラム」をコードに明示しておくと、

後から読んだときに「この処理は何を使っているのか」がすぐ分かる。 仕様変更でカラムが増減したときも、keys を見れば影響範囲が分かる。

というメリットがあります。

手を動かして「カラム抽出」の感覚をつかむ

次のコードを実行して、

オブジェクト配列から「複数カラム」「単一カラム」を抽出する感覚をつかんでみてください。

function pickColumns(objects, keys) {
  if (!Array.isArray(objects) || objects.length === 0) {
    return [];
  }

  if (!Array.isArray(keys) || keys.length === 0) {
    return [];
  }

  return objects.map((obj) => {
    const picked = {};
    keys.forEach((key) => {
      picked[key] = obj[key];
    });
    return picked;
  });
}

function pluckColumn(objects, key) {
  if (!Array.isArray(objects) || objects.length === 0) {
    return [];
  }

  return objects.map((obj) => obj[key]);
}

function demo() {
  const users = [
    { id: 1, name: "Alice", email: "alice@example.com", active: true },
    { id: 2, name: "Bob",   email: "bob@example.com",   active: false },
  ];

  console.log("=== pickColumns (id, name) ===");
  console.log(pickColumns(users, ["id", "name"]));

  console.log("=== pluckColumn (id) ===");
  console.log(pluckColumn(users, "id"));
}

demo();
JavaScript

まとめ:カラム抽出ユーティリティで「必要な情報だけを軽く扱う」

カラム抽出は、 「配列の中から、業務的に必要な情報だけを取り出して、軽く・扱いやすくするためのユーティリティ」です。

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

export function pickColumns(objects, keys) { ... }
export function pluckColumn(objects, key) { ... }
JavaScript

そして、

CSV/Excel 出力、 ログ出力、 別 API へのデータ連携、 集計前の前処理

といったところでは、必ず「カラム抽出」を通して、 “必要なものだけ”を渡す。

こう決めておくと、 データが軽くなり、コードの意図もはっきりして、 業務ロジックがかなり整理されていきます。

「全部持っていく」から「必要なものだけ持っていく」へ。 その切り替えを支えるのが、カラム抽出ユーティリティです。

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