HOWTO · JavaScript
JavaScript 中陣列的子集
在今天的文章中,我們將學習如何在 JavaScript 中提取陣列的子集。
本頁內容
需要將選取範圍放入新陣列、同時保留原陣列時,請使用 slice()。需要從原陣列移除、取代或插入元素時,請使用 splice()。兩種方法都會回傳陣列,但只有 splice() 會修改呼叫它的陣列。
使用 slice() 擷取子集而不修改陣列
slice(start, end) 會回傳所選範圍的淺層複本。start 索引所指的元素會包含在結果中;選用的 end 索引則不包含在內。省略 end 時,會選取到最後一個元素。由於回傳的是淺層複本,巢狀物件仍會以參照方式共用;不過,在結果中新增或移除元素不會改變原陣列。
索引從零開始計算。負索引會從陣列末端往回計算:-1 是最後一個元素,-2 是倒數第二個元素。若起始索引等於或大於陣列長度,結果會是空陣列;若結束索引超出陣列長度,則會視為陣列長度。若正規化後的結束索引小於或等於起始索引,結果也會是空陣列。這些規則讓你能輕鬆選取開頭、中間或末尾的範圍,不必先計算每個索引。
假設範圍從索引 1 開始、到索引 4 結束,選取到的位置會是 1、2 和 3。將引數理解為「第一個納入的位置」和「第一個排除的位置」,在配合使用者介面或進行計算時會更容易調整範圍。回傳陣列是獨立的容器,因此之後變更其中的元素,不會改變原陣列的順序。
執行以下範例:
本節中的程式碼以及顯示的標籤或輸出仍為英文。
const scores = [12, 18, 25, 31, 44];
const middleScores = scores.slice(1, 4);
console.log(JSON.stringify(middleScores));
console.log(JSON.stringify(scores));
[18,25,31]
[12,18,25,31,44]
範例會先印出選取的範圍,再印出未變更的原陣列。若要選取末尾的元素,可以使用負起始索引,例如 scores.slice(-2);若要複製整個陣列,可以使用 scores.slice()。
如需了解此方法的完整行為,請參閱 MDN 的 slice() 參考文件。
使用 splice() 擷取並變更陣列元素
splice(start, deleteCount, ...items) 會直接修改原陣列。它從 start 開始,最多移除 deleteCount 個元素,接著在該位置插入提供的項目。此方法會依照原有順序,將被移除的元素放進新陣列並回傳。若需要同時查看修改後的原陣列和回傳值,請保留原陣列的參照。
start 索引從零開始計算。負起始索引會從陣列末端往回計算;若起始索引超出陣列長度,則會視為陣列末端,項目可附加在該處。省略 deleteCount 時,會從 start 移除所有後續元素。傳入 0 則不會移除任何元素,因此提供的項目會直接插入,不影響現有元素。負的 deleteCount 也不會移除任何元素。若 deleteCount 大於剩餘元素數量,移除動作會在陣列末端停止。
執行以下範例:
本節中的程式碼以及顯示的標籤或輸出仍為英文。
const fruits = ['Kiwi', 'Orange', 'Apple', 'Banana'];
const removedFruits = fruits.splice(0, 2, 'Mango');
console.log(JSON.stringify(removedFruits));
console.log(JSON.stringify(fruits));
["Kiwi","Orange"]
["Mango","Apple","Banana"]
範例會先印出被移除的值,再印出已修改的 fruits 陣列;被移除的範圍會由 Mango 取代。
若要移除索引 1 之後的所有元素,請使用 fruits.splice(1)。若要在索引 1 插入元素而不移除任何元素,請使用 fruits.splice(1, 0, 'Pear')。如需了解此方法的詳細資訊,請參閱 MDN 的 splice() 參考文件。
如何選擇 slice() 或 splice()
若要讀取或傳遞陣列中的一部分,同時保留原有順序,請選擇 slice()。它的結束索引不包含在結果中,回傳值則是選取範圍的淺層複本。若工作需要編輯現有陣列,請選擇 splice();它會回傳被移除的部分,若沒有刪除任何元素,回傳值可能是空陣列。
例如,使用 const page = items.slice(offset, offset + pageSize) 可產生一頁資料,而不會修改 items。若確實要從 items 移除這些元素,則可使用 const removed = items.splice(index, count)。若後續程式碼仍需要原陣列,請優先使用 slice(),或先明確複製陣列,再呼叫 splice()。
原文也提供完整的 JSFiddle 範例,可供互動試用這兩種方法。