splice
、?slice
、?pop
?和?shift
。數組的排序方法是穩定且非原地算法的嗎?要記住所有 JavaScript 數組方法以及它們之間的區別并不容易。它們的名稱相似,就好像直接從同義詞詞典中提取一樣。
這個數組速查表列出了 JavaScript 中通常需要的所有數組方法,以及不需要的方法都不包含在內。就是這么簡單!為了讓您更容易理解,我基于常見用例制作了這個速查表。
在我們開始之前,關于不可變性(Immutability)有一點需要注意。本文中使用的所有函數都是不可變的,簡而言之,這意味著在使用這些方法時,您永遠不會改變原始數組。不可變性在現代 JavaScript 中非常重要。
Stack Overflow?中對?
Immutability
?的理解。
盡管這些方法在各自的操作中都是不可變的,但您仍然不能完全確保不可變性。如果在不可變數組中包含可變數據類型(數組、對象、函數),您仍然可以修改數組內部的可變數據。我們將這種數組稱為淺不可變數組,與深不可變數組相對,后者僅包含不可變項。
-
在數組的開頭添加元素
要將一個項目添加到數組的開頭,使用數組擴展(array spreading)。不要使用?
unshift
?方法,因為它會修改原始數組。const arr = [1, 2, 3]; const result = [0, ...arr]; console.log(result); // [0, 1, 2, 3]
-
在數組的末尾添加元素
要在數組的末尾追加一個項目,使用數組展開(array spreading)。不要使用?
push
?方法,因為它會修改原始數組。const arr = [1, 2, 3]; const result = [...arr, 4]; console.log(result); // [1, 2, 3, 4]
-
從數組的開頭移除一個元素
要移除數組中的第一個項目,使用?
slice
?方法。不要使用?shift
?或?splice
?方法,因為它們會修改原始數組。const arr = [1, 2, 3]; // 保留索引1及其之后的所有元素 const result = arr.slice(1); console.log(result); // [2, 3]
-
從數組的末尾移除一個元素
要移除數組中的最后一個項目,使用?
slice
?方法。不要使用?pop
?或?splice
?方法,因為它們會修改原始數組。const arr = [1, 2, 3]; // 保留索引0及其之后的所有元素,除了數組中的一個元素。 const result = arr.slice(0, -1); console.log(result); // [1, 2]
-
在數組中的特定索引位置插入元素
要在數組的特定索引位置添加一個元素,可以使用?
toSpliced
?方法。不要使用?splice
?方法,因為它會修改原始數組。const arr = [1, 2, 3]; // 保留索引1,刪除0個元素,在索引1插入元素 "one point five",并保留其后的所有元素。 const result = arr.toSpliced(1, 0, "one point five"); console.log(result); // [1, "one point five", 2, 3]
-
在數組中替換特定索引位置的元素
要在數組中替換特定索引位置的元素,可以使用?
toSpliced
?或?with
?方法。不要使用?splice
?方法,因為它會修改原始數組。const arr = [1, 2, 3]; ? // 使用 toSpliced。 // 保留索引1,刪除1個元素,在索引1插入元素 "two",并保留其后的所有元素。 const result1 = arr.toSpliced(1, 1, "two"); console.log(result1); // [1, "two", 3] ? // 使用 with。 // 復制舊數組 arr,將索引1替換為 "two"。 const result2 = arr.with(1, "two"); console.log(result2); // [1, "two", 3]
-
從數組中刪除特定索引位置的元素
要從數組中移除一個項,可以使用?
toSpliced
?方法。不要使用?splice
?方法,因為它會修改原始數組。const arr = [1, 2, 3]; ? // 在索引1處刪除1個元素。 const result = arr.toSpliced(1, 1); console.log(result); // [1, 3]
-
從數組中根據值移除一個元素
要從數組中刪除特定的值,可以使用?
filter
?方法。不要將?indexOf
?與?splice
?方法一起使用,因為它會修改原始數組。const arr = [1, 2, 3]; const result = arr.filter((element) => element !== 2); console.log(result); // [1, 3]
-
從數組中根據屬性移除對象
要從數組中刪除具有特定屬性的對象,可以使用?
filter
?方法。不要將?findIndex
?與?splice
?方法一起使用,因為它會修改原始數組。const arr = [{ num: 1 }, { num: 2 }, { num: 3 }]; const result = arr.filter((obj) => obj.num !== 2); console.log(result); // [{ num: 1 }, { num: 3 }]
-
檢查數組是否包含一個元素
要檢查數組是否包含一個值,可以使用?
includes
?方法。const arr = [1, 2, 3]; const result = arr.includes(2); console.log(result); // true
-
檢查數組是否包含具有特定屬性的對象
要檢查數組是否包含具有特定屬性的對象,可以使用?
some
?方法。const arr = [{ num: 1 }, { num: 2 }, { num: 3 }]; const result = arr.some((obj) => obj.num === 2); console.log(result); // true
-
檢查數組中的所有對象是否都具有特定屬性
要檢查數組中的每個對象是否都具有特定屬性,可以使用?
every
?方法。const arr1 = [{ num: 1 }, { num: 2 }, { num: 3 }]; const result1 = arr1.every((obj) => obj.num === 2); console.log(result1); // false ? const arr2 = [{ num: 2 }, { num: 2 }, { num: 2 }]; const result2 = arr2.every((obj) => obj.num === 2); console.log(result2); // true
-
將數組轉換為對象
要將數組轉換為自定義對象,可以使用?
reduce
?方法。// 將鍵映射到值的函數。 const arr1 = [1, 2, 3]; const result1 = arr1.reduce((acc, cur, index) => {acc[`attr${index}`] = cur;return acc; }, {}); console.log(result1); // { attr0: 1, attr1: 2, attr2: 3 } ? // 一個計算出現次數的函數可能如下所示。 const arr2 = ["a", "b", "c", "c"]; const result2 = arr2.reduce((acc, cur) => {if (acc[cur]) {acc[cur] += 1;} else {acc[cur] = 1;}return acc; }, {}); console.log(result2); // { a: 1, b: 1, c: 2 }) ? // 將數組元素映射到布爾值的函數可以如下所示。 // 即,將數組轉換為對象鍵。 const arr3 = ["a", "b", "c"]; const truthValues = ["b", "c"]; const result3 = arr3.reduce((acc, cur) => {acc[cur] = truthValues.includes(cur);return acc; }, {}); console.log(result3); // { a: false, b: true, c: true }
-
將對象數組轉換為對象
要將對象數組轉換為對象,可以使用?
Object.assign
方法和數組擴展語法。const arr = [{ attr1: 1 }, { attr2: 2 }, { attr3: 3 }]; const result = Object.assign({}, ...arr); console.log(result); // { attr1: 1, attr2: 2, attr3: 3 }
-
將對象轉換為數組
要從對象創建一個數組,可以使用?
Object.keys
、Object.values
?或?Object.entries
?方法,可能與?map
?方法一起使用。const obj = { a: 1, b: 2, c: 3 }; ? // 鍵的數組。 const result1 = Object.keys(obj); console.log(result1); // ["a", "b", "c"] ? // 值的數組。 const result2 = Object.values(obj); console.log(result2); // [1, 2, 3] ? // 鍵值對象的數組。 const result3 = Object.entries(obj).map(([key, value]) => ({ key, value })); console.log(result3); // [{ key: "a", value: 1 }, { key: "b", value: 2 }, { key: "c", value: 3 }]
在某些情況下,可以鏈式使用一些?
map
?和?filter
方法來修改和篩選值。const obj = { a: 1, b: 2, c: 3 }; ? // 具有平方值大于3的值的數組。 const result1 = Object.values(obj).map((value) => value * value).filter((value) => value > 3); console.log(result1); // [4, 9] ? // 具有值大于1的鍵值對象的數組。 const result2 = Object.entries(obj).map(([key, value]) => ({ key, value })).filter((keyValueObj) => keyValueObj.value > 1); console.log(result2); // [{ key: "b", value: 2 }, { key: "c", value: 3 }]
-
合并兩個數組
要合并兩個 JavaScript 數組,可以使用?
concat
?方法或數組的擴展語法。不要使用?push
?方法,因為它會修改原始數組。const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; ? // 使用 concat 方法更快。 const combinedArray1 = arr1.concat(arr2); console.log(combinedArray1); // [1, 2, 3, 4, 5, 6] ? // 使用擴展語法可能更可讀。 const combinedArray2 = [...arr1, ...arr2]; console.log(combinedArray2); // [1, 2, 3, 4, 5, 6]
-
對數組進行排序
如果要按值對數組進行排序,可以使用?
toStorted
方法。toStorted
?方法是穩定的,這意味著它會保持相互相等的元素的順序不變。而且,該方法是非原地的,通常這是一件好事,因為它不會修改現有的數組。不要使用?sort
?方法,因為它會進行原地排序,從而修改原始數組。// 對字符串進行排序。 let arr1 = ["b", "c", "a"]; const result1 = arr1.toSorted(); console.log(result1); // ["a", "b", "c"] ? // 注意:數字是按其 toString 值進行排序的,而不是按其數值進行排序的! const arr2 = [10, 1, 5]; const result2 = arr2.toSorted(); console.log(result2); // [1, 10, 5] ? // 若要對數字進行排序,可以使用比較器。 const arr3 = [10, 1, 5]; const result3 = arr3.toSorted((a, b) => a - b); console.log(result3); // [1, 5, 10]
-
對對象數組進行排序
要按值對數組進行排序,請使用具有比較函數的?
toStorted
?方法。比較函數用于確定兩個值中哪個應該首先排序。toStorted
?方法是穩定的,這意味著它會保持相互相等的元素的順序不變。此方法不會原地排序,通常這是一件好事,因為它不會修改現有的數組。不要使用?sort
?方法,因為它會修改原始數組。const arr = [{ num: 3 }, { num: 1 }, { num: 2 }]; ? // 如果比較函數返回正值,objA 將在 objB 之前排序。 const byNumberAttribute = (objA, objB) => objA.num - objB.num; const result1 = arr.toSorted(byNumberAttribute); console.log(result1); // [{ num: 1 }, { num: 2 }, { num: 3 }] ? // 更通用的比較函數。 const byAttribute = (attr) => (objA, objB) => objA[attr] - objB[attr]; const result2 = arr.toSorted(byAttribute("num")); console.log(result2); // [{ num: 1 }, { num: 2 }, { num: 3 }] ? // 注意:比較函數必須返回整數值。 // 如果需要對其他數據類型進行排序,可以返回 1、0 或 -1。 const arr3 = [{ letter: "c" }, { letter: "a" }, { letter: "b" }]; const alphabetically = (objA, objB) => {if (objA.letter < objB.letter) {return -1;} ?if (objA.letter > objB.letter) {return 1;} ?// objA === objBreturn 0; }; const result3 = arr3.toSorted(alphabetically); console.log(result3); // [{ letter: 'a' }, { letter: 'b' }, { letter: 'c' }]
-
反轉數組
要反轉數組中的所有值,請使用?
toReversed
?方法。const arr = [1, 2, 3]; const result = arr.toReversed(2); console.log(result); // [3, 2, 1]
-
從數組中移除重復項
要從數組中移除重復的元素,可以使用?
filter
?方法或使用集合(Set
)。const arr = [1, 2, 3, 2, 1]; ? // 使用 filter 方法。 const result1 = arr.filter((item, index) => arr.indexOf(item) === index); console.log(result1); // [1, 2, 3] ? // 使用 Set。 const result2 = [...new Set(arr)]; console.log(result2); // [1, 2, 3]
在這篇博客中,我們深入研究了JavaScript
數組的20個必備高效技巧,旨在幫助您更智能、更高效地處理數組數據。我們從數組的基礎操作開始,逐步引導您掌握更高級的技能。
我們學到了如何在數組的開頭和末尾添加、移除元素,以及如何在特定索引位置插入、替換和刪除元素,而不會影響原始數組。我們了解了如何檢查數組中是否包含特定元素,以及如何將數組轉換為對象或對象數組轉換為對象或數組。我們還探討了如何合并兩個數組,對數組進行排序,包括對象數組,以及如何反轉數組和去除重復項。
這些技巧不僅僅是一堆代碼示例,它們代表了更深刻的概念,涉及到JavaScript
中數組操作的核心原則。通過掌握這些技巧,您將能夠:
- 編寫更整潔、可讀和高效的代碼。
- 更智能地處理數組數據,無論是在前端還是后端開發中。
- 解決各種常見問題,從數據過濾到數據轉換和排序。
- 提高您的編碼技能,使您成為
JavaScript
數組操作的專家。
不管您是新手還是經驗豐富的開發者,這些技巧都將成為您工具箱中的寶貴資產。JavaScript
數組是開發中不可或缺的一部分,精通數組操作將使您的項目更具競爭力。
如果您想更深入地了解這些技巧,我鼓勵您動手實踐。嘗試在自己的項目中應用它們,以加深理解。最重要的是,保持好奇心,不斷學習和探索,因為JavaScript
的世界充滿了無限的可能性。
感謝您閱讀這篇博客,希望它為您提供了有價值的知識,幫助您在JavaScript
數組操作中取得更大的成功。如果您有任何問題或反饋,請隨時與我聯系。愿您的編碼之路充滿挑戰和成就! 🚀