JavaScript 陣列處理常用方法

圖片來源: 網路

push

將資料塞入陣列的最後一筆

1
2
3
4
var data = ['A', 'B', 'C']
data.push('D')

console.log(data) // ['A', 'B', 'C', 'E']

pop

將資料最後一筆移除,無參數

1
2
3
4
var data = ['A', 'B', 'C']
data.pop()

console.log(data) // ['A', 'B']

unshift

將資料塞入陣列的第一筆

1
2
3
4
var data = ['B', 'C']
data.unshift('A')

console.log(data) // ['A', 'B', 'C']

shift

將資料第一筆移除,無參數

1
2
3
4
var data = ['A', 'B', 'C']
data.shift()

console.log(data) // ['B', 'C']

splice

splice 有兩種不同的用法

移除原始陣列特定索引

帶入一個或兩個參數 splice(指定索引, 欲刪除的數量)

起始索引 - 要從哪個索引開始刪除。
欲刪除的數量 - 從起始索引開始算往後山幾筆資料,若不帶入則從起始索引開始後的所有資料都刪除。

1
2
3
4
var data = ['A', 'B', 'C', 'D', 'E']
data.splice(2, 1) // 從索引2的位置刪除1筆資料

console.log(data) // ['A', 'B', 'D', 'E']
1
2
3
4
var data = ['A', 'B', 'C', 'D', 'E']
data.splice(2) // 索引2後的資料全部刪除

console.log(data) // ['A', 'B']

指定從某個索引塞入資料,並且選擇從該索引往後刪除幾筆資料(或不刪除)

必須帶入三個參數 splice(指定索引, 欲刪除的數量, 欲塞入的資料)

1
2
3
4
var data = ['A', 'B', 'C', 'D', 'E']
data.splice(2, 0, '塞入資料') // 從索引2的位置,刪除0筆資料,並且在該位置塞入資料。

console.log(data) // ['A', 'B', '塞入資料', 'D', 'E']

slice

slice 與 splice 很像,slice 取得兩個指定索引間的所有資料,且不會改變原始陣列。

slice( 起始索引[包含], 結束索引[不包含] )

1
2
3
4
5
6
arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']; 
arr.slice(2, 5);
// ["C", "D", "E"]

console.log(arr)
// ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] 原始陣列不變

若只帶第一個參數則是從該參數開始到最後的值都取出

1
2
3
4
5
6
arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']; 
arr.slice(2);
// ["C", "D", "E", "F", "G", "H"]

console.log(arr)
// ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] 原始陣列不變

concat

可以用來合併兩個陣列

1
2
3
4
arr = ['A', 'B'] 
arr.concat(['C', 'D', 'E']) // ["A", "B", "C", "D", "E"]

console.log(arr) // ['A', 'B'] 原始陣列不變

可以用來複製陣列

1
2
3
4
5
arr = ['A', 'B'] 
var arr_copy = arr.concat([])

console.log(arr_copy) // ['A', 'B']
console.log(arr) // ['A', 'B'] 原始陣列不變

join

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

1
2
arr = ['A', 'B', 'C', 'D']
console.log(arr.toString()) // A,B,C,D

若要移除逗號或是以別的東西代替逗號,就可以使用 join

1
2
3
arr = ['A', 'B', 'C', 'D']
console.log(arr.join('')) // ABCD
console.log(arr.join('/')) // A/B/C/D

reverse

將原始陣列排序相反過來

1
2
3
4
var data = ['A', 'B', 'C', 'D', 'E']
data.reverse()

console.log(data) // ["E", "D", "C", "B", "A"]

sort

sort() 方法會原地(in place)對一個陣列的所有元素進行排序,並回傳此陣列。預設的排序順序是根據字串的 Unicode 編碼位置(code points)而定。

不帶入函式

1
2
3
4
5
6
7
8
9
var months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// ["Dec", "Feb", "Jan", "March"]

var array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// [1, 100000, 21, 30, 4]

帶入函式 ( 依數字大小排序 )

陣列元素們將根據比較函式之回傳值來排序。如果 a 和 b 為被比較之兩元素,則:

  • 若 compare(a, b) 的回傳值小於 0,則 a 排在 b 前面。
  • 若 compare(a, b) 的回傳值大於 0,則 b 排在 a 前面。
  • 若 compare(a, b) 回傳 0,則 a 與 b 皆不會改變彼此的順序,但會與其他全部的元素比較來排序。
1
var arr = [1, 3, 5, 10, 7, 6]
1
2
3
4
5
6
7
8
9
10
11
arr.sort(function(a, b) {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
// a 必須等於 b
return 0;
})
// output: [1, 3, 5, 6, 7, 10]

縮寫

  • 升冪

    1
    2
    3
    4
    arr.sort(function(a, b){
    return a - b
    // output: [1, 3, 5, 6, 7, 10]
    })
  • 降冪

    1
    2
    3
    4
    arr.sort(function(a, b){
    return b - a
    // output: [10, 7, 6, 5, 3, 1]
    })

三元運算子縮寫

  • 升冪

    1
    2
    3
    4
    arr.sort(function(a, b){
    return a > b ? 1 : -1 // 翻譯: 如果a>b就回傳-1,不是就回傳1
    // output: [1, 3, 5, 6, 7, 10]
    })
  • 降冪

    1
    2
    3
    4
    arr.sort(function(a, b){
    return a < b ? 1 : -1 // 翻譯: 如果a<b就回傳-1,不是就回傳1
    // output: [10, 7, 6, 5, 3, 1]
    })

MDN - sort()

indexOf

用於取的陣列的索引位子,從前面開始找,且找到符合條件的元素後即回傳該元素索引。
下面例子雖然後面還有一個 B 符合條件,但因為前面已經找到了,所以不會在往下找。

1
2
arr = ['A', 'B', 'C', 'D', 'E', 'B']
arr.indexOf('B') // 1

在陣列內找不到該值則回傳 -1

1
2
arr = ['A', 'B', 'C', 'D', 'E']
arr.indexOf('Hi') // -1

運用

將兩個陣列不重複的值取出,組成一個新陣列

1
2
var arr = ['A', 'B', 'C', 'D', 'E']
var arr2 =['A', 'B']

解答

1
2
3
var newArr = arr.filter((item) => {
if (arr2.indexOf(item) == -1) return item
})
1
2
console.log(newArr)
// output: ["C", "D", "E"]

lastIndexOf

跟 indexOf 太一樣的地方是indexOf 只要 一找到資料就會立刻回傳,而 lastIndexOf 會找完全部陣列再回傳最後一筆符合條件的資料索引位子。

1
2
arr = ['A', 'B', 'A', 'D', 'A']
arr.lastIndexOf('A') // 4

====以下例子會使用這個陣列作範例====

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let data = [
{
name: '老媽',
money: 2000
},
{
name: '老爸',
money: 1000
},
{
name: '大哥',
money: 500
},
{
name: '小妹',
money: 100
}
]

傳統 for

1
2
3
4
5
6
var len = data.length

for(let i=0; i<len; i++) {
console.log(data[i]) // 陣列內的物件
console.log(i) // 索引
}

for in

  • 此篇只有 for in 可用於物件
1
2
3
4
for (let index in data) {
console.log(data[index]) // 陣列內的物件
console.log(index) // 索引
}

forEach

  • forEach 沒在 return 的,所以寫了也沒用。
1
2
3
4
5
data.forEach(function(item, index, arr) {
console.log(item) // 陣列內的物件
console.log(index) // 索引
console.log(arr) //相當於console.log(data) (較不常使用)
})

filter

  • filter()回傳一個陣列,回傳的是所有判斷為 true 的值,很適合用在搜尋所有符合條件的資料

1
2
3
var filterData = data.filter(function(item, index, arr) {
return item.money > 600
})

find

  • 類似 filter() ,但只回傳陣列中第一個為true的值,適合用在判斷該陣列有沒有任一個符合特定條件目標
1
2
3
var findData = data.find(function(item, index, arr) {
return item.money > 600
})

map

  • 判斷條件為 true 的話,可以 return 自定義內容。
  • 使用 map() 需要 return 一個值,他會透過函式內所回傳的值組合成一個陣列
    • 回傳的新陣列長度一定會等於該遍歷資料的長度。
    • 如果不回傳任何東西,會形成長度同該遍歷資料的 undefined 陣列。

1
2
3
var mapData = data.map(function(item, index, arr) {
return
})


1
2
3
var mapData = data.map(function(item, index, arr) {
return item.money > 600
})


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var mapData = data.map(function(item, index, arr) {
if (item.money > 600) {
return {
...item, // ES6
discribtion: '真有錢'
}
}else {
return {
...item,
discribtion: '窮'
}
}
})

// ES6以前寫法
// var mapData = data.map(function(item, index, arr) {
// if (item.money > 600) {
// item.discribtion = '真有錢'
// return item
// }else {
// item.discribtion = '窮'
// return item
// }
// })

every

  • 檢查陣列值是否符合條件,這僅會回傳一個值 truefalse,適合用來檢查陣列中的內容是否全部都符合特定條件。
1
2
3
4
5
6
7
data.every(function(item, index, arr) {
return item.money > 200 // 回傳false,因為小妹只有100塊
})

data.every(function(item, index, arr) {
return item.money > 10 // 回傳true,所有人都超過100塊
})

some

  • every() 類似,但只要一個符合就會回傳 true
1
2
3
data.some(function(item, index, arr) {
return item.money > 1500 // 回傳true
})

reduce

  • prev 參數的值為最後帶入的數字 (此例為0)
  • 下例(1) prev 初始值是0,跑第二次迴圈時 prev的值變成第一次迴圈所 return 的值,依此類推。
1
2
3
4
5
6
7
8
9
/* 加總所有人的錢,reduceData最後結果為3600 */
var reduceData = data.reduce(function(prev, item, index, arr) {
return prev + item.money // 跑第一次迴圈時值為初始值0,第二次的值為0加上老媽的錢2000,第三次是2000+老爸的錢1000,依此類推。
}, 0) // 傳入初始化值為 0 (為prev賦值0)

/* 篩選錢最多的,reduceData最後結果為2000 */
var reduceData = data.reduce(function(prev, item, index, arr) {
return Math.max(prev, item.money) // Math.max() 會回傳帶入的兩個數中較大的數
}, 0)

reduceRight

類似於 reduce ,但 reduceRight的執行順序是由後往前執行。

加總陣列內的數字

如果是加總陣列內的數字,不管是由前往後或是由後往前,結果是看不出差別的。

1
var arr = [1, 2, 3, 4, 5];

reduce

1
2
3
4
arr.reduce((prev, item) => {
return prev + item;
})
// 15

reduceRight

1
2
3
4
arr.reduceRight((prev, item) => {
return prev + item;
})
// 15

組字串

如果是組字串就能看出差異

1
var arr = ['1', '2', '3', '4', '5'];

reduce

1
2
3
4
arr.reduce((prev, item) => {
return prev + item;
})
// "12345"

reduceRight

1
2
3
4
arr.reduceRight((prev, item) => {
return prev + item;
})
// "54321"

findIndex

1
2
3
4
5
6
7
8
var arr = [5, 12, 8, 130, 44];

arr.findIndex(function(item) {
return item > 13;
})

// 3
`

其他

預設的陣列行為內的 this 是指向 window (本篇中除了 reduce() 是傳入初始資料),如果要改,可以在 function 後傳入

1
let newArr = ['A', 'B','C']
1
2
3
var newData = data.forEach(function(item, index, arr){
console.log(this) // ['A', 'B','C']
}, newArr); // 傳入的物件newArr,替代 this,如果無則是指向 window

參考資料

陣列取出重覆與不重複值˙的方法
[偷米騎巴哥]操作JS陣列的20種方式
[偷米騎巴哥]操作JS陣列的20種方式 - 筆記整理
hsiangfeng - 關於JS陣列20種操作的方法