本文 AI 產出,尚未審核

多維陣列(Arrays)

簡介

在 JavaScript 中,陣列(Array)是最常用的資料結構之一,幾乎每個前端或後端專案都會與它打交道。當資料不只是一列線性的元素,而是呈現「表格」或「樹狀」的形態時,我們就需要使用多維陣列(Multi‑dimensional Array)來儲存與操作。
多維陣列讓我們可以在同一個變數中,保存二維(矩陣)、三維(立體座標)甚至更高維度的資料,這在 遊戲開發、資料視覺化、矩陣運算 等情境下尤為重要。掌握多維陣列的創建、存取與遍歷技巧,能讓程式碼更具可讀性與可維護性,也為日後學習更進階的演算法奠定基礎。

核心概念

1. 多維陣列的基本結構

在 JavaScript 裡,多維陣列其實是「陣列的陣列」。例如,二維陣列可以寫成:

// 2×3 的二維陣列(2 列、3 行)
const matrix = [
  [1, 2, 3],   // 第 0 列
  [4, 5, 6]    // 第 1 列
];
  • matrix[0][2] 取得第 0 列第 2 行的元素,結果為 3
  • 取值的順序是「外層陣列 → 內層陣列」,因此先指定列(row),再指定行(column)。

2. 動態產生多維陣列

手寫每一層的陣列在資料量大時不切實際,常會用迴圈或 Array.from 產生:

// 建立 4×5 的二維陣列,預設值為 0
const rows = 4, cols = 5;
const grid = Array.from({ length: rows }, () =>
  Array.from({ length: cols }, () => 0)
);
console.log(grid);

技巧:使用 Array.from 的第二個參數可以直接寫入初始化函式,讓程式更簡潔。

3. 三維以上的陣列

三維陣列常見於 3D 圖形、棋盤遊戲的立體棋局,結構為「陣列的陣列的陣列」:

// 2×3×4 的三維陣列,值為其索引之和
const depth = 2, rows3D = 3, cols3D = 4;
const cube = Array.from({ length: depth }, (_, d) =>
  Array.from({ length: rows3D }, (_, r) =>
    Array.from({ length: cols3D }, (_, c) => d + r + c)
  )
);
console.log(cube);

4. 常用的遍歷方法

4.1 for 迴圈(最直觀)

for (let i = 0; i < matrix.length; i++) {
  for (let j = 0; j < matrix[i].length; j++) {
    console.log(`matrix[${i}][${j}] = ${matrix[i][j]}`);
  }
}

4.2 forEach 結合解構賦值

matrix.forEach((row, i) => {
  row.forEach((value, j) => {
    console.log(`row ${i}, col ${j}: ${value}`);
  });
});

4.3 flatflatMap(將多維展平)

// 將二維陣列展平成一維陣列
const flatArray = matrix.flat();   // [1,2,3,4,5,6]

// 同時展平兩層
const deep = [[[1]], [[2]], [[3]]];
console.log(deep.flat(2)); // [1,2,3]

注意flat 只在 ES2019 以上支援,舊環境需自行實作或使用 polyfill。

5. 多維陣列的拷貝與深層複製

直接賦值只會產生引用,修改其中一層會影響原始陣列:

const original = [[1, 2], [3, 4]];
const shallowCopy = original;   // 兩者指向同一個陣列
shallowCopy[0][0] = 99;
console.log(original[0][0]);    // 99

若要深層複製,可以使用 JSON.parse(JSON.stringify(...)) 或遞迴:

// 簡易深層複製(適用於純數值/字串/布林的陣列)
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy[0][0] = 7;
console.log(original[0][0]);    // 99(不受影響)

⚠️:JSON 方法無法處理 undefinedfunctionSymbol 等特殊值,若有需求請自行實作遞迴拷貝。

常見陷阱與最佳實踐

陷阱 可能的結果 解決方式
陣列長度不一致(所謂「鋸齒狀」陣列) 讀取 matrix[i][j] 時出現 undefined,可能導致程式錯誤 在建立時統一長度,或在存取前先檢查 Array.isArray(matrix[i])
引用傳遞 修改子陣列會影響其他變數 使用深層複製或 map 產生新陣列
過度巢狀迴圈 效能低、可讀性差 若維度 > 2,考慮使用 flatten 後一次遍歷,或抽象成 函式(如 forEach2D
flat 深度不夠 仍留下子陣列 明確傳入正確的 depth,或使用 Infinity 完全展平
忘記 let / const 在迴圈中使用 var 變數提升導致意外行為 永遠使用 letconst,避免作用域混淆

最佳實踐

  1. 明確宣告維度:在程式碼註解或變數命名中說明陣列的維度,例如 const board3D = ... // depth × rows × cols
  2. 使用函式封裝遍歷:將常見的二維/三維迭代抽成 forEach2DforEach3D,提升重用性。
  3. 避免硬編碼索引:使用 for...of 搭配 entries() 取得索引,減少錯誤。
  4. 適時展平:若只需要一次性檢查所有元素,flat(Infinity) 可以簡化程式。
  5. 測試邊界:寫單元測試驗證空陣列、單層陣列、不同長度的子陣列皆能正確處理。

實際應用場景

1. 棋盤遊戲(如井字棋、圍棋)

二維陣列可直接映射棋盤格子,board[row][col] 代表每個格子的狀態(空、黑子、白子)。配合 深層複製,可實作「回溯」或「悔棋」功能。

// 3×3 井字棋板,0 = 空,1 = X,2 = O
let ticTacToe = Array.from({ length: 3 }, () => Array(3).fill(0));

function place(row, col, player) {
  if (ticTacToe[row][col] !== 0) return false; // 已佔用
  ticTacToe[row][col] = player;
  return true;
}

2. 圖像處理(像素矩陣)

每個像素的 RGB 值可用三維陣列表示:image[y][x][channel](channel = 0~2)。透過遍歷,可快速執行濾鏡、亮度調整等運算。

function invertColors(image) {
  image.forEach(row => {
    row.forEach(pixel => {
      // 255 - 原值 = 反相顏色
      pixel[0] = 255 - pixel[0]; // R
      pixel[1] = 255 - pixel[1]; // G
      pixel[2] = 255 - pixel[2]; // B
    });
  });
}

3. 三維座標系統(遊戲、模擬)

在 3D 遊戲中,常用 三維陣列 來保存地圖格子或體素(voxel)資訊,例如 world[depth][row][col] 表示特定高度的地形類型。

// 建立 10×10×10 的體素世界,預設為空氣 (0)
const world = Array.from({ length: 10 }, () =>
  Array.from({ length: 10 }, () => Array(10).fill(0))
);

// 放置一個方塊
function setBlock(z, y, x, type) {
  world[z][y][x] = type;
}

4. 數據分析(矩陣運算)

在統計或機器學習前端實作時,常需要 矩陣相乘轉置 等操作。多維陣列提供了直觀的資料結構。

// 簡易矩陣相乘(2×3 * 3×2)
function multiply(A, B) {
  const rowsA = A.length, colsA = A[0].length;
  const colsB = B[0].length;
  const result = Array.from({ length: rowsA }, () => Array(colsB).fill(0));

  for (let i = 0; i < rowsA; i++) {
    for (let k = 0; k < colsA; k++) {
      for (let j = 0; j < colsB; j++) {
        result[i][j] += A[i][k] * B[k][j];
      }
    }
  }
  return result;
}

總結

多維陣列是 JavaScript 中強而有力的資料容器,從簡單的二維表格到複雜的三維座標,都能以「陣列的陣列」方式直觀表達。掌握以下要點,能讓你在開發中更加得心應手:

  • 建立方式:使用巢狀 Array.from 或迴圈動態產生,避免手寫大量硬編碼。
  • 存取與遍歷:熟悉 forforEachflat 等方法,根據需求選擇最適合的遍歷策略。
  • 深層拷貝:了解引用與拷貝的差異,必要時使用深層複製避免副作用。
  • 最佳實踐:統一維度、封裝遍歷、避免過深巢狀迴圈,並在關鍵位置加入單元測試。

透過本篇的概念說明與實務範例,你已具備在 遊戲開發、圖像處理、資料分析 等領域使用多維陣列的基礎。未來若需要更高階的矩陣運算,亦可結合 TypedArrayWebGL 或第三方數學函式庫(如 mathjs)進一步提升效能與功能。祝你在 JavaScript 的陣列世界裡玩得開心、寫得順手!