🧑💻JavaScript數據結構與算法-HowieCong
務必要熟悉JavaScript使用再來學!
數組
-
在 JavaScript 中,數組是一種特殊的對象,用於存儲多個值的有序集合
1. 數組的創建
// 方括號+元素內容 const arr = [1,2,3] // 構造函數,等價於 const arr = [] const arr = new Array(); // 長度為7的數組 const arr = new Array(7); // length: 7 // 創建一個長度確定、同時每一個元素的值也確定的數組 // 需求為每個元素的值為6,調用fill方法,給fill一個6 const arr = (new Array(7)).fill(6) // (7)[6,6,6,6,6,6,6] // 使用擴展運算符複製數組 // 擴展運算符(...)可以用於複製一個數組,創建一個淺拷貝的新數組 const originalArr = [1, 2, 3]; const copiedArr = [...originalArr]; console.log(copiedArr); // [1, 2, 3] // 使用Array.from()的映射功能 // Array.from()除了可以從類數組或可迭代對象創建數組,還可以接受一個映射函數作為第二個參數,對每個元素進行處理 const arr = Array.from([1, 2, 3], num => num * 2); console.log(arr); // [2, 4, 6]
2. 一維數組的訪問和遍歷
- 訪問數組的元素,直接在中括號中指定其索引即可:
arr[0] // 訪問索引下標為0的元素
-
遍歷數組三種常見方法:
如果沒有特殊需要,統一使用for循環來實現遍歷,從性能上看,for循環遍歷起來是最快
(1)for循環
- 最基礎的方法 => 通過循環數組的下標 => 依次訪問值
const len = arr.lengthh
for(let i = 0;i < len;i++){
// 輸出數組的元素值,輸出當前索引
console.log(arr[i],i)
}
(二)forEach方法
- 通過foreach方法中傳入函數的第一個入參和第二個入參,也可以取到數組每個元素的值及其索引
arr.forEach((item,index) => {
// 輸出數組的元素值,輸出當前索引
console.log(item,index)
})
(三)map方法
- 和foreach方法差不多,區別在map會根據傳入的函數邏輯對數組每個元素進行處理,返回一個全新的數組,map不單是遍歷,而是在遍歷的基礎上再加工。需要對數組內容做批量修改、同時修改的邏輯又要高度一致,就可以調用map來達到我們的目的
```js
const newArr = arr.map((item,index) =>{
// 輸出數組的元素值,輸出當前索引
console.log(item,index)
// 在當前元素的值基礎上加1
return item + 1
})
// 通過map返回一個全新的數組,數組的每個元素的值都是再其現有元素值的基礎上+1後的結果
```
(四)for...of循環
for...of循環是 ES6 引入的一種遍歷可迭代對象的語法,數組是可迭代對象,因此可以使用for...of循環來遍歷數組元素
const arr = [1, 2, 3];
for (const item of arr) {
console.log(item);
}
(五)for...in循環
- 雖然
for...in循環主要用於遍歷對象的可枚舉屬性,但也可以用於數組。不過需要注意的是,for...in循環會遍歷數組的所有可枚舉屬性,包括自定義的屬性,並且遍歷順序可能不是按照數組索引的順序
const arr = [1, 2, 3];
arr.customProperty = 'hello';
for (const index in arr) {
console.log(index, arr[index]);
}
3. 二維數組
二維數組其實就是數組套數組,就是每個元素都是數組的數組
特點:相對於一維數組像一條線,而二維數組像一個面,在數學中,形如這樣長方形排列的複數或實數集合,被稱為矩陣,因此二維數組的別名就叫矩陣
const arr = [
[1,2,3],
[1,2,3],
[1,2,3],
[1,2,3],
[1,2,3]
]
4. 二維數組的初始化
在for循環(簡單且性能還不錯)中每次迭代我們都通過[]來創建一個新的數組,這樣不會引用指向問題帶來的尷尬
const len = arr.length
for(let i = 0;i < length;i++){
// 將數組的每一個坑位初始化為數組
arr[i] = []
}
5. fill的侷限性(不推薦使用在二維數組)
// 初始一個二維數組
const arr = (new Array(7)).fill([])
// 修改某個坑的值為1
arr[0][0] = 1 // 這一列的元素都設為了1
fill的工作機制,當給fill傳入一個入參,如果這個入參的類型是引用類型,那麼fill在填充坑位時填充的其實就是入參的引用。上述例子的七個數組對應同一個引用、指向的是同一塊內存空間,本質上是同一個數組。因此當改變了第0行的第0個元素的值時,第1-6行的第0個元素的值也都是改變的
6. 二維數組的訪問
和一維數組差不多,區別在於我們現在需要的是兩層循環
// 緩存外部數組的長度
const outerLen = arr.length
for(let i = 0; i < outterLen; i++){
// 緩存內部數組的長度
const innerLen = arr[i].length
for(let j = 0; j < innerLen; j++){
// 輸出數組的值,輸出數組的索引
console.log(arr[i][j],i,j)
}
}
一維數組用for數組只需一層循環,二維數組就是兩層,三維就是三層,以此類推,n維就是需要n層來遍歷
7. 二維數組的淺拷貝和深拷貝
淺拷貝只會複製數組的一層,而深拷貝會遞歸地複製數組的所有層級
//淺拷貝
const original2DArr = [[1,2],[3,4]];
const shallow = [...original2DArr];
shallowCopy[0][0] = 10;
console.log(shallowCopy[0][0]); // 10
// 深拷貝
function deepCopy(arr){
return JSON.parse(JSON.stiringify(arr));
}
const deepCopyArr = deepCopy(original2DArr);
deepCopyArr[0][0] = 20;
console.log(original2DArr[0][0]);// 10
8. 數組API合集(記憶)
以上是數組的基礎知識,數組還有很多特性和技巧,在後續這個系列文章會羅列的,記憶API是個痛苦的事!下面是一些常用API,按照不同功能的對這些API進行分類:
8.1 數組創建與轉換
-
Array.from()- 作用:從一個類數組對象或可迭代對象創建一個新的、淺拷貝的數組實例
const str = 'hello'; const arr = Array.from(str); console.log(arr); // ['h', 'e', 'l', 'l', 'o'] -
Array.of()- 作用:創建一個具有可變數量參數的新數組實例,而不考慮參數的數量或類型
const arr = Array.of(1, 2, 3);
console.log(arr); // [1, 2, 3]
8.2 數組元素訪問與修改
-
at()- 作用:接收一個整數值並返回該索引對應的元素,允許使用負整數從數組末尾開始計數
const arr = [10, 20, 30];
console.log(arr.at(-1)); // 30
-
copyWithin()- 作用:淺複製數組的一部分到同一數組中的另一個位置,並返回它,不會改變原數組的長度
const arr = [1, 2, 3, 4, 5];
arr.copyWithin(0, 3);
console.log(arr); // [4, 5, 3, 4, 5]
-
fill()- 作用:用一個固定值填充一個數組中從起始索引到終止索引內的全部元素
const arr = new Array(3);
arr.fill(1);
console.log(arr); // [1, 1, 1]
8.3 數組迭代
-
entries()- 作用:返回一個新的 Array Iterator 對象,該對象包含數組中每個索引的鍵 / 值對
const arr = ['a', 'b', 'c'];
const iterator = arr.entries();
for (const [index, value] of iterator) {
console.log(index, value);
}
-
every()- 作用:測試一個數組內的所有元素是否都能通過某個指定函數的測試。
const arr = [1, 2, 3, 4];
const isAllPositive = arr.every(num => num > 0);
console.log(isAllPositive); // true
-
filter()- 作用:創建一個新數組,其包含通過所提供函數實現的測試的所有元素
const arr = [1, 2, 3, 4];
const evenNumbers = arr.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4]
-
find()- 作用:返回數組中滿足提供的測試函數的第一個元素的值,否則返回
undefined
- 作用:返回數組中滿足提供的測試函數的第一個元素的值,否則返回
const arr = [1, 2, 3, 4];
const firstEven = arr.find(num => num % 2 === 0);
console.log(firstEven); // 2
-
findIndex()- 作用:返回數組中滿足提供的測試函數的第一個元素的索引,若沒有找到則返回 -1
const arr = [1, 2, 3, 4];
const index = arr.findIndex(num => num % 2 === 0);
console.log(index); // 1
-
flat()- 作用:創建一個新數組,所有子數組元素遞歸地連接到該數組中,直到達到指定的深度
const arr = [1, [2, [3]]];
const flattened = arr.flat(2);
console.log(flattened); // [1, 2, 3]
-
flatMap()- 作用:首先使用映射函數映射每個元素,然後將結果壓縮成一個新數組
const arr = [1, 2, 3];
const result = arr.flatMap(num => [num * 2]);
console.log(result); // [2, 4, 6]
-
forEach()- 作用:對數組的每個元素執行一次提供的函數。
const arr = [1, 2, 3];
arr.forEach(num => console.log(num));
-
includes()- 作用:判斷一個數組是否包含一個指定的值,根據情況返回
true或false
- 作用:判斷一個數組是否包含一個指定的值,根據情況返回
const arr = [1, 2, 3];
const hasTwo = arr.includes(2);
console.log(hasTwo); // true
-
indexOf()- 作用:返回在數組中可以找到一個給定元素的第一個索引,如果不存在,則返回 -1
const arr = [1, 2, 3];
const index = arr.indexOf(2);
console.log(index); // 1
-
join()- 作用:將一個數組(或一個類數組對象)的所有元素連接成一個字符串並返回這個字符串
const arr = ['a', 'b', 'c'];
const str = arr.join('-');
console.log(str); // 'a-b-c'
-
lastIndexOf()- 作用:返回指定元素在數組中的最後一個的索引,如果不存在則返回 -1
const arr = [1, 2, 3, 2];
const lastIndex = arr.lastIndexOf(2);
console.log(lastIndex); // 3
-
map()- 作用:創建一個新數組,其結果是該數組中的每個元素都調用一個提供的函數後返回的結果
const arr = [1, 2, 3];
const squared = arr.map(num => num * num);
console.log(squared); // [1, 4, 9]
-
reduce()- 作用:對數組中的每個元素執行一個由您提供的
reducer函數(升序執行),將其結果彙總為單個返回值。
- 作用:對數組中的每個元素執行一個由您提供的
const arr = [1, 2, 3];
const sum = arr.reduce((acc, cur) => acc + cur, 0);
console.log(sum); // 6
-
reduceRight()- 作用:接受一個函數作為累加器(
reducer)和數組的每個值(從右到左)將其減少為單個值
- 作用:接受一個函數作為累加器(
const arr = [1, 2, 3];
const result = arr.reduceRight((acc, cur) => acc - cur);
console.log(result); // 0
-
reverse()- 作用:將數組中元素的位置顛倒,並返回該數組
const arr = [1, 2, 3];
arr.reverse();
console.log(arr); // [3, 2, 1]
-
some()- 作用:測試數組中是不是至少有 1 個元素通過了被提供的函數測試
const arr = [1, 2, 3];
const hasEven = arr.some(num => num % 2 === 0);
console.log(hasEven); // true
-
sort()- 作用:對數組的元素進行排序,並返回數組。
const arr = [3, 1, 2];
arr.sort((a, b) => a - b);
console.log(arr); // [1, 2, 3]
-
toLocaleString()- 作用:返回一個字符串表示數組中的元素。數組中的元素將使用各自的
toLocaleString方法轉成字符串,這些字符串將使用一個特定語言環境的字符串(例如一個逗號 ",")隔開
- 作用:返回一個字符串表示數組中的元素。數組中的元素將使用各自的
const arr = [1, 'a', new Date()];
const str = arr.toLocaleString();
console.log(str);
-
toString()- 作用:返回一個字符串,表示指定的數組及其元素
const arr = [1, 2, 3];
const str = arr.toString();
console.log(str); // '1,2,3'
8.4 數組元素添加與刪除
-
pop()- 作用:從數組中刪除最後一個元素,並返回該元素的值。此方法會更改數組的長度。
const arr = [1, 2, 3];
const last = arr.pop();
console.log(last); // 3
console.log(arr); // [1, 2]
-
push()- 作用:將一個或多個元素添加到數組的末尾,並返回該數組的新長度
const arr = [1, 2];
const newLength = arr.push(3);
console.log(newLength); // 3
console.log(arr); // [1, 2, 3]
-
shift()- 作用:從數組中刪除第一個元素,並返回該元素的值。此方法更改數組的長度
const arr = [1, 2, 3];
const first = arr.shift();
console.log(first); // 1
console.log(arr); // [2, 3]
-
splice()- 作用:通過刪除或替換現有元素或者原地添加新的元素來修改數組,並以數組形式返回被修改的內容
const arr = [1, 2, 3];
const removed = arr.splice(1, 1, 4);
console.log(removed); // [2]
console.log(arr); // [1, 4, 3]
-
unshift()- 作用:將一個或多個元素添加到數組的開頭,並返回該數組的新長度
const arr = [2, 3];
const newLength = arr.unshift(1);
console.log(newLength); // 3
console.log(arr); // [1, 2, 3]
8.5 數組拼接與切片
-
concat()- 作用:用於合併兩個或多個數組。此方法不會更改現有數組,而是返回一個新數組
const arr1 = [1, 2];
const arr2 = [3, 4];
const newArr = arr1.concat(arr2);
console.log(newArr); // [1, 2, 3, 4]
-
slice()- 作用:返回一個新的數組對象,這一對象是一個由
begin和end決定的原數組的淺拷貝(包括begin,不包括end)。原始數組不會被改變
- 作用:返回一個新的數組對象,這一對象是一個由
const arr = [1, 2, 3, 4];
const sliced = arr.slice(1, 3);
console.log(sliced); // [2, 3]
❓其他
1. 疑問與作者HowieCong聲明
- 如有疑問、出錯的知識,請及時點擊下方鏈接添加作者HowieCong的其中一種聯繫方式或發送郵件到下方郵箱告知作者HowieCong
- 若想讓作者更新哪些方面的技術文章或補充更多知識在這篇文章,請及時點擊下方鏈接添加里面其中一種聯繫方式或發送郵件到下方郵箱告知作者HowieCong
- 聲明:作者HowieCong目前只是一個前端開發小菜鳥,寫文章的初衷只是全面提高自身能力和見識;如果對此篇文章喜歡或能幫助到你,麻煩給作者HowieCong點個關注/給這篇文章點個贊/收藏這篇文章/在評論區留下你的想法吧,歡迎大家來交流!
2. 作者社交媒體/郵箱-HowieCong
- HowieCong Social Meida : Wechat|Instagram|Feishu...
- HowieCong Mail : howiecong@163.com