JavaScript | 多次元配列(配列の中に配列)

JavaScript JavaScript
スポンサーリンク

JavaScriptの多次元配列をHTMLテーブルで表示する練習

まずは「配列の配列」をテーブルに変換する感覚を掴みましょう。段階的に練習できるように、シンプル→応用の順で例を用意しました。


基本練習: 二次元配列をそのまま表にする

HTMLとJavaScriptだけで、多次元配列をテーブル化します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <title>配列→テーブル表示</title>
  <style>
    table { border-collapse: collapse; margin-top: 12px; }
    th, td { border: 1px solid #999; padding: 6px 10px; text-align: left; }
    caption { font-weight: bold; margin-bottom: 6px; }
  </style>
</head>
<body>
  <h1>多次元配列をHTMLテーブルに表示</h1>

  <div id="app"></div>

  <script>
    // 練習用データ(行 = レコード、列 = 項目)
    const data = [
      ["Yamada", 28, "Tokyo"],
      ["Suzuki", 35, "Fukuoka"],
      ["Honda", 24, "Sendai"]
    ];

    // テーブル生成関数(見出しなし版)
    function renderTable(containerId, rows) {
      const container = document.getElementById(containerId);
      const table = document.createElement('table');

      // 各行と各セルを作成
      rows.forEach(row => {
        const tr = document.createElement('tr');
        row.forEach(cell => {
          const td = document.createElement('td');
          td.textContent = cell;
          tr.appendChild(td);
        });
        table.appendChild(tr);
      });

      container.appendChild(table);
    }

    renderTable('app', data);
  </script>
</body>
</html>
HTML
  • 目的: 配列を二重のループでテーブルの行・列に変換する感覚を掴む。
  • ポイント: forEachで「行→セル」を順に作る。document.createElementappendChildでDOMを積み上げる。

見出し付きテーブル: ヘッダー行を追加する

列名があるとグッと実用的になります。

<div id="app2"></div>
<script>
  const headers = ["Name", "Age", "City"];
  const rows = [
    ["Yamada", 28, "Tokyo"],
    ["Suzuki", 35, "Fukuoka"],
    ["Honda", 24, "Sendai"]
  ];

  function renderTableWithHeader(containerId, headers, rows) {
    const container = document.getElementById(containerId);
    const table = document.createElement('table');

    // キャプション(任意)
    const caption = document.createElement('caption');
    caption.textContent = "User list";
    table.appendChild(caption);

    // ヘッダー
    const thead = document.createElement('thead');
    const trHead = document.createElement('tr');
    headers.forEach(h => {
      const th = document.createElement('th');
      th.textContent = h;
      trHead.appendChild(th);
    });
    thead.appendChild(trHead);
    table.appendChild(thead);

    // 本体
    const tbody = document.createElement('tbody');
    rows.forEach(row => {
      const tr = document.createElement('tr');
      row.forEach(cell => {
        const td = document.createElement('td');
        td.textContent = cell;
        tr.appendChild(td);
      });
      tbody.appendChild(tr);
    });
    table.appendChild(tbody);

    container.appendChild(table);
  }

  renderTableWithHeader('app2', headers, rows);
</script>
HTML
  • 目的: <thead>, <tbody>, <th>を使って構造化。
  • ポイント: データの列順とヘッダーの整合性を保つ。

応用: オブジェクト配列から列選択して表示

よくある「オブジェクトの配列」から、必要なプロパティだけ列にします。

<div id="app3"></div>
<script>
  const users = [
    { name: "Yamada", age: 28, city: "Tokyo", active: true },
    { name: "Suzuki", age: 35, city: "Fukuoka", active: false },
    { name: "Honda",  age: 24, city: "Sendai",  active: true }
  ];

  // 表示する列を宣言的に定義
  const columns = [
    { key: "name", label: "Name" },
    { key: "age",  label: "Age" },
    { key: "city", label: "City" },
    { key: "active", label: "Active" }
  ];

  function renderObjectTable(containerId, data, columns) {
    const container = document.getElementById(containerId);
    const table = document.createElement('table');

    // ヘッダー
    const thead = document.createElement('thead');
    const trHead = document.createElement('tr');
    columns.forEach(col => {
      const th = document.createElement('th');
      th.textContent = col.label;
      trHead.appendChild(th);
    });
    thead.appendChild(trHead);
    table.appendChild(thead);

    // 本体
    const tbody = document.createElement('tbody');
    data.forEach(item => {
      const tr = document.createElement('tr');
      columns.forEach(col => {
        const td = document.createElement('td');
        td.textContent = item[col.key];
        tr.appendChild(td);
      });
      tbody.appendChild(tr);
    });
    table.appendChild(tbody);

    container.appendChild(table);
  }

  renderObjectTable('app3', users, columns);
</script>
HTML
  • 目的: 現実的なデータ構造をテーブルにマッピングする。
  • ポイント: 列定義を配列にし、拡張しやすくする。

エラーハンドリング・不均一データへの備え

列数が揃っていない配列でも安全に描画します。

<div id="app4"></div>
<script>
  const messy = [
    ["A", 1],
    ["B", 2, "extra"],
    ["C"] // 列不足
  ];

  function renderSafeTable(containerId, rows) {
    const container = document.getElementById(containerId);
    const table = document.createElement('table');

    // 最大列数を計算
    const maxCols = rows.reduce((m, r) => Math.max(m, r.length), 0);

    const tbody = document.createElement('tbody');
    rows.forEach(row => {
      const tr = document.createElement('tr');
      for (let i = 0; i < maxCols; i++) {
        const td = document.createElement('td');
        td.textContent = row[i] !== undefined ? row[i] : ""; // 欠損は空表示
        tr.appendChild(td);
      }
      tbody.appendChild(tr);
    });

    table.appendChild(tbody);
    container.appendChild(table);
  }

  renderSafeTable('app4', messy);
</script>
HTML
  • 目的: 不揃いなデータでも崩れず表示。
  • ポイント: 先に最大列数を測ってから各行を埋める。

スタイリングと小技

  • 中央寄せ: 数値列だけ中央寄せなど、列に応じてクラスを付ける。
  • 交互行: 視認性UPのためのストライプ表示。
  • クリック操作: 行クリックで詳細表示や選択状態を切り替え。
/* 交互行 */
tbody tr:nth-child(odd) { background: #fafafa; }
/* 数値用 */
td.num { text-align: center; }
CSS
// 数値列にクラス付与(例: 2列目と3列目)
columns.forEach((col, idx) => {
  // 例:列定義にtypeを持たせて判定しても良い
});
JavaScript

練習課題

  1. 合計列の追加: 点数表に「合計」と「平均」列を追加して表示する。
    • ヒント: row.slice(1)で点数部分を取り出し、reduceで合計を出す。
  2. ソート機能: ヘッダーをクリックすると、その列で昇順/降順に並び替える。
    • ヒント: Array.prototype.sortを使い、クリック時に再描画。
  3. フィルタリング: 入力欄で「City」に含まれる文字で絞り込み。
    • ヒント: includesで判定して、絞り込んだ配列を再表示。
  4. 空値の表示ルール: 欠損データは「—」と表示して目立たせる。
    • ヒント: cell == null ? "—" : cell のように処理。

つまづきポイントの回避策

  • Label: 行と列のインデックスを混同しない
    • 行が先、列が後。data[rowIndex][colIndex]の順。
  • Label: DOMの再作成を忘れない
    • 再描画時は、古いテーブルを消してから新しいテーブルを入れる。
  • Label: データとヘッダーの列数整合性
    • 列定義を1か所に集約し、コード重複を避ける。

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