Skip to main content

如何用 JavaScript 將一個 array 轉換成一個 object(舉例:根據 id 做 key)

概念簡單說明

  • 輸入陣列:一個物件陣列,每個元素都是物件(object),裡面有 id 屬性(通常是數字或字串,用來當唯一鍵)。

  • 轉換邏輯:遍歷陣列,把每個物件的 id 當作物件的鍵(key),整個物件當作值(value)。如果有重複 id,後面的會覆蓋前面的。

  • 為什麼這樣做? 物件的鍵是雜湊(hash)存取,超快!例如,原本要用 find() 找 id=2 的元素,現在直接 obj[2] 就拿到。

  • 注意:id 如果是數字,物件鍵會自動轉成字串(但存取時數字和字串都行)。如果陣列是空的,結果就是空物件

範例輸入

我們用一個簡單的陣列來示範,假設這是從 API 拿到的商品清單:

const items = [
{ id: 1, name: '蘋果', price: 50 },
{ id: 2, name: '香蕉', price: 30 },
{ id: 3, name: '橘子', price: 40 }
];
  • 這裡每個元素是物件,有 id、name 和 price 屬性。

步驟解釋

  1. 開啟 JavaScript 環境:按 F12 開啟瀏覽器開發者工具,切到 Console 分頁(或用 Node.js)。這是測試的最簡單方式。

  2. 宣告陣列變數:輸入上面的 const items = [...] 並按 Enter。這會把資料放進變數 items。

  3. 使用 reduce() 方法轉換

    • reduce() 是陣列的內建方法,它會從左到右處理每個元素,累積結果。

    • 語法:array.reduce((accumulator, currentValue) => { ... }, initialValue);

      • accumulator:累積的結果,從初始值開始(我們用空物件 {})。

      • currentValue:目前處理的陣列元素(這裡是 { id: 1, name: '蘋果', price: 50 } 這種物件)。

      • 在回呼函式裡:accumulator[currentValue.id] = currentValue; – 把 id 當鍵,整個物件當值。

      • 最後 return accumulator; 回傳更新後的物件,讓下一個元素繼續加。

  4. 把結果存到新變數:例如 const itemObj = items.reduce(...);

  5. 印出結果檢查:用 console.log(itemObj); 看物件內容。

  6. 測試存取:例如 console.log(itemObj[2]); 應該輸出 { id: 2, name: '香蕉', price: 30 }。注意:用 itemObj[2]itemObj['2'] 都行。

  7. 如果出錯:檢查 Console 錯誤,通常是 id 拼錯、陣列沒宣告,或括號沒對。重打一次就好。

完整程式碼

你可以直接複製這段到 Console 執行,一次按 Enter 就好(多行用 Shift+Enter)。

// 步驟 1: 宣告陣列(輸入資料)
const items = [
{ id: 1, name: '蘋果', price: 50 },
{ id: 2, name: '香蕉', price: 30 },
{ id: 3, name: '橘子', price: 40 }
];

// 步驟 2: 使用 reduce() 轉換成物件(以 id 為鍵)
const itemObj = items.reduce((accumulator, currentValue) => {
// 把目前物件的 id 當作鍵,整個物件當作值
accumulator[currentValue.id] = currentValue;
// 回傳累積的物件,讓下一個元素繼續加入
return accumulator;
}, {}); // 初始值是空物件 {}

// 步驟 3: 印出結果檢查
console.log(itemObj);
// 預期輸出: { '1': { id: 1, name: '蘋果', price: 50 }, '2': { id: 2, name: '香蕉', price: 30 }, '3': { id: 3, name: '橘子', price: 40 } }

// 步驟 4: 測試存取特定 id 的物件
console.log(itemObj[2]); // 輸出: { id: 2, name: '香蕉', price: 30 }
console.log(itemObj['3'].name); // 輸出: 橘子(存取巢狀屬性)

輸出結果

執行 console.log(itemObj); 後,你會看到類似這樣:

{
'1': { id: 1, name: '蘋果', price: 50 },
'2': { id: 2, name: '香蕉', price: 30 },
'3': { id: 3, name: '橘子', price: 40 }
}
  • 鍵是字串形式(如 '1'),但你可以用數字 1 存取 itemObj[1],JS 會自動轉換。

  • 如果陣列有重複 id,例如再加 { id: 2, name: '另一個香蕉' },最後的會覆蓋:itemObj[2] 變成新的一個。

變化版:如果 id 是字串

假如你的 id 是字串(如 'a001'),程式碼一樣適用!改陣列成:

const items = [
{ id: 'a001', name: '蘋果', price: 50 },
{ id: 'a002', name: '香蕉', price: 30 }
];

結果鍵就是 'a001' 和 'a002',存取用 itemObj['a001']

小提示與注意事項

  • 錯誤常見原因

    • 陣列元素沒有 id:會變成 undefined 鍵,Console 會印 { undefined: { ... } } – 檢查資料。

    • 空陣列:itemObj 就是 ,沒問題。

    • 大陣列:JS 處理得很好,不用擔心效能。

  • 其他方法:現代 JS 有 Object.fromEntries(),但 reduce() 更直覺且相容舊瀏覽器。例如:Object.fromEntries(items.map(item => [item.id, item])); – 但我建議先用 reduce() 練手。

  • 練習建議:試著加一個新元素到陣列,再執行轉換,看結果變化。或改 id 成其他屬性(如 name 當鍵),但記得 name 可能重複。

  • 為什麼不直接用 Map? Map 也是鍵值對,但物件更輕量,且在 JSON 裡好傳。如果你需要保留數字鍵類型,用 Map 更好:new Map(items.map(item => [item.id, item])); – 但這次我們專注物件。