關於 JavaScript 陣列20種操作的方法

前言

這篇文章主要是觀看了[偷米騎巴哥]操作JS陣列的20種方式而撰寫的,因為覺得這張圖真的是精華

所以就乾脆寫一篇文章記錄一下操作陣列的20種方式。

Github:操作JS陣列的20種方式

Youtube:[偷米騎巴哥]操作JS陣列的20種方式

陣列操作的20種方法

操作陣列的方式在[偷米騎巴哥]操作JS陣列的20種方式中提到可分為【有可能會因為一些操作改變原始陣列】與【不會改變原始陣列】這兩種大類,實際這樣講很難懂,所以實際來練習看看就知道了。

有可能會因為一些操作改變原始陣列

先預設一個範例陣列

1
any = ['A', 'B', 'C', 'D', 'E'];

shift

shift() 這個功能會取陣列中第一筆資料,但是要注意是【抽】出來,並不是單純的取出。
※shift() 是不用帶參數的。

1
2
3
any = ['A', 'B', 'C', 'D', 'E'];
any.shift(); // 取得陣列第一筆A
any

所以這時候在執行一次 any 這個陣列,就會發現 A 消失了。

MDN shift

unshift

有抽出陣列第一筆的方法,那麼就會有【塞】回去陣列最前面的方法。
※unshift() < 括號內帶入欲塞入的資料。

1
2
3
4
any = ['A', 'B', 'C', 'D', 'E'];
any.shift(); // 取得陣列第一筆A
any.unshift("A"); // 塞回陣列第一筆A
any

此時就可以看到陣列恢復原本的範例了。

MDN unshif

pop

如果要抽出陣列中最後一筆的話就使用 pop()。

1
2
3
any = ['A', 'B', 'C', 'D', 'E'];
any.pop(); // 抽走最後一個E
any

MDN pop

push

那如果要放回去到陣列最後一筆呢?就使用 push()。

1
2
3
4
any = ['A', 'B', 'C', 'D', 'E'];
any.pop(); // 抽走最後一個E
any.push("E"); // 在陣列最後一筆放入E
any

MDN push

splice

splice 有一點特殊,它可以有兩種做法

取得(刪除)陣列特定位子

如果要針對陣列上特定索引 or 位子做刪除就可以使用 splice()。
※splice(start,deleteContent) 可以帶入2個參數

  • 第一個參數是索引位子
  • 第二個參數是刪除幾筆資料 or 要連續取出幾筆數量,若不帶入參數就會直接依照第一個參數所以開始取到(刪除)到最後

1
2
any = ['A', 'B', 'C', 'D', 'E'];
any.splice(2); // 2 > 代表我從B開始,然後就會發現回傳了C、D、E

這時候再來查看 any ,就會只剩下 A 跟 B

但若只要取出一筆 or 刪除一筆呢?就帶入第二個參數即可。

1
2
any = ['A', 'B', 'C', 'D', 'E'];
any.splice(2,1); // 他就會從陣列中第二個開始,然後只取得一筆就是C

這時候再查看原有的 any 陣列就會發現 C 不見了。

1
2
3
any = ['A', 'B', 'C', 'D', 'E'];
any.splice(2,1); // 他就會從陣列中第二個開始,然後只取得一筆就是C
any

※splice 重點在於第二個參數,若不帶入,就會依照起始索引之後全部取光(刪除)

塞回陣列特定位子

同理前面,有取得特定位子就會有塞回去特定位子的方法,但是也是一樣使用 splice。
若要用 splice 的塞回特定位子的陣列方法,就要使用 splice 中的的三個參數。

1
2
3
any = ['A', 'B', 'D', 'E'];
any.splice(2,0,'C'); // 第二個參數可以帶入0,這樣子就不會刪除任何資料,僅需要在地三個參數塞入要塞入的資料即可
any

MDN Splice

sort

sort 跟 reverse 是屬於相同的東西,都是針對陣列去做排序。

而 sort 通常都會透過 function 來回傳陣列,通常會帶入兩個參數 a、 b,若不帶入 function sort 預設會依照字串來排序,所以若數字要從小到大做排序就必須帶入 function。

偷米騎巴哥的做法是這樣

1
2
3
4
5
any = [14, 30, 35, 42, 5, 16, 70, 98, 19, 100]; 
any.sort(function(a, b) {
return a > b ? 1 : -1;
});
any

而我的作法是這樣

1
2
3
4
5
any = [14, 30, 35, 42, 5, 16, 70, 98, 19, 100]; 
any.sort(function(a, b) {
return a - b;
});
any

這兩者應該都可以。

若要反過來從小到大就是這樣寫

1
2
3
4
5
any = [14, 30, 35, 42, 5, 16, 70, 98, 19, 100]; 
any.sort(function(a, b) {
return a < b ? 1 : -1;
});
any

1
2
3
4
5
any = ['A', 'B', 'C', 'D', 'E']; 
any.sort(function(a, b) {
return b - a;
});
any

※sort 可以做排序,但是是使用字串去做排序,所以如果要針對數字排序,就要記得帶入 function,所以如果單純只是針對字串做排序,就可以不用寫 function。

MDN sort

reverse

reverse 就是將目前陣列排序給反轉過來的一種方式。

1
2
3
any = ['A', 'B', 'C', 'D', 'E']; 
any.reverse();
any

MDN reverse

length

一般最常使用的就是 length,這可以取得陣列的長度。
※length 起始索引並不是由0開始計算,而是1開始。

1
2
any = ['A', 'B', 'C', 'D', 'E']; 
any.length;

但是 length 也可以拿來改變陣列,舉例我要將陣列給清空。

1
2
3
any = ['A', 'B', 'C', 'D', 'E']; 
any.length = 0;
any

又或者是只保留陣列中3筆資料

1
2
3
any = ['A', 'B', 'C', 'D', 'E']; 
any.length = 3;
any

MDN length

join

預設若把陣列轉換為字串就會以逗號作為一個分隔。

但如果要把逗號改成另一種的話,例如斜線呢,就要使用 join。

1
2
any = ['A', 'B', 'C', 'D', 'E']; 
any.join('/'); // 也可帶入空字串

MDN join

reduce

reduce 感覺起來就是累加,比較常見用於將陣列中所有數字累加起來,這個方法也很類似一個迴圈的概念。

但是使用 reduce 是必須帶入 function,而這 function 通常會帶入兩個參數,通常會叫 prev (前一個), next (後一個)

所以 reduce 在執行的時候就會像這樣。

prev 將1帶入 prev 而 next 就是2 > 1 + 2 = 3 接下來剛剛算出來的結果3帶入至 prev,然後 next 帶入4 > 3 + 4 後面以此類推 7 + 5 …進而得到55這個答案。

但是這邊需注意 reduce 必須回傳 (return),否則會出現 undefined。

1
2
3
4
any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
any.reduce(function(prev, next){
return prev + next;
});

這邊要注意,若帶入的是字串就會變成字串組合而已。

1
2
3
4
any = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; 
any.reduce(function(prev, next){
return prev + next;
});

MDN reduce

reduce​Right

由於 reduce 是從第一累加到最後一筆,所以也會有一個方法是反過來累加的,從最後一筆累積到第一筆。

通常若使用數字來累積是看不出差異的。

1
2
3
4
any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
any.reduceRight(function(prev, next){
return prev + next;
});

但如果是字串的話就可以看出差異性。

1
2
3
4
any = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; 
any.reduceRight(function(prev, next){
return prev + next;
});

MDN reduceRight

indexOf

indexOf 主要用於取的陣列的索引位子。

1
2
any = ['A', 'B', 'C', 'D', 'E']; 
any.indexOf('B'); // indexOf索引是從0開始,所以A位子代表 0,B則為1

如果是在找不到的狀況下就會回傳 -1

1
2
any = ['A', 'B', 'C', 'D', 'E']; 
any.indexOf('F');

※至於為甚麼會回傳-1的原因是,因為 indexOf 陣列索引的起始是0,所以0代表A,若出現0的話就會跟A打在一起,所以只要找不到就會出現-1。

MDN indexOf

lastIndexOf

lastIndexOf 跟 indexOf 會稍微不太一樣,indexOf 只要【一找到資料就會立刻回傳】,而 lastIndexOf 會找完全部陣列再回傳最後一筆資料索引位子。

所以舉例來講,A有三個

1
2
any = ['A', 'B', 'A', 'D', 'A']; 
any.indexOf('A'); 此時會發現indexOf會回傳他第一個找到的A

若是 lastIndexOf 就會不一樣了。

1
2
any = ['A', 'B', 'A', 'D', 'A']; 
any.lastIndexOf('A'); // lastIndexOf他會找到最後一筆,所以最後一筆A在陣列索引4

※所以 indexOf 與 lastIndexOf 的差異在於,lastIndexOf 會跑遍陣列全部的資料再回傳,而 indexOf 只要一發現就會立刻回傳而不會跑遍整個陣列。

MDN lastIndexOf

some

會檢查陣列中的結果是否相同,而 some 只要陣列中【有一個符合結果相同就會回傳 ture】,簡單來講只要陣列中有滿足條件就會全部回傳 true。

※這邊要注意 some 要帶入 function。

1
2
3
4
any = ['A', 'B', 'C', 'D', 'E']; 
any.some(function(val) {
return val === 'C'
});

MDN some

every

如果要檢查陣列而且要【完全相同才回傳true】,就要使用 every。

1
2
3
4
any = ['C', 'B', 'C', 'C', 'C']; 
any.every(function(val) {
return val === 'C'
});

所以若當陣列每一個都符合時就會回傳 true。

1
2
3
4
any = ['C', 'C', 'C', 'C', 'C']; 
any.every(function(val) {
return val === 'C'
});

every 也可以用來檢查每一個字串的長度。

1
2
3
4
any = ['A', 'B', 'C', 'D', 'E']; 
any.every(function(val) {
return val.length === 1;
});

MDN every

forEach

forEach 是 ES6 的東西,跟 for loop 很像,但是 forEach 簡化了 for loop。

以往我們撰寫 for loop 都是這樣

1
2
3
4
any = ['A', 'B', 'C', 'D', 'E']; 
for (let i = 0; i < any.length; i++){
console.log(any[i],i); // i 代表索引值
}

而 forEach 幫助我們可以不用寫 length 跟 i++ 等等,forEach 提供三種參數可供使用

  • 第一個參數代表物件
  • 第二個參數代表索引
  • 第三個參數代表陣列本身

1
2
3
4
any = ['A', 'B', 'C', 'D', 'E']; 
any.forEach(function(item, index, array) {
console.log(item, index, array);
})

MDN forEach

不會改變原始陣列

先預設一個範例陣列

1
any = ['A', 'B', 'C', 'D', 'E'];

Map

與 forEach 非常類似,但是 map 會 return 一個值,並且產生一個【新陣列出來】。

map 提供三個參數可使用

  • 第一個參數代表物件
  • 第二個參數代表索引
  • 第三個參數代表陣列本身

1
2
3
4
any = ['A', 'B', 'C', 'D', 'E']; 
any.map(function(item, index, array) {
return item + item;
})

所以使用 Map 是不會對原有的陣列受到任何影響的。

1
any

MDN Map

filter

filter 主要用於篩選的做法,也與 forEach 類似。

如果要挑出偶數的做法就是這樣

1
2
3
4
any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
any.filter(function(item) {
return item % 2 === 0; // 可以被2整除並等於0的就代表偶數。
})

若是基數的話

1
2
3
4
any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
any.filter(function(item) {
return item % 2 === 0; // 不能被2整除並不等於0的就代表基數。
})

當然原有的陣列 any 也不會受到影響。

1
any

MDN filter

slice

slice 與 splice 有點類似,也是取得範圍,但是 slice 可以從特定範圍變成一個新陣列。

例如我要取得5~9的數字

1
2
any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
any.slice(4, 9);

當然 slice 對於原始陣列也不會有任何副作用

1
any

MDN slice

concat

如果有兩個陣列要串接再一起就要使用 concat。

1
2
any = ['A', 'B']; 
any.concat(['C', 'D', 'E']);

但是要注意 concat 一樣隊原有陣列並不會有影響。

1
any

MDN concat

結語

經過偷米騎巴哥這個影片、圖片及解釋之後對於陣列的20種操作方式更加深刻,其中偷米騎巴哥還特別做一個範例為什麼黑色的區塊會【有可能因為操作的關係而導致改變原始陣列】。

1
2
3
4
5
any = ['A', 'B', 'C', 'D', 'E']; 
any.forEach(function(item, index, array) {
any[index] = item+item;
})
any

參考

[偷米騎巴哥]操作JS陣列的20種方式

操作JS陣列的20種方式GitHub

MDN

0%