參考資料 Array
join()
用字元連接陣列
join()
會把「陣列的每一個元素」用我想要的「字元」連接在一起之後,產生另一個新的「string」回傳
- 字元只會插在陣列的空隙,陣列的頭尾不會放入字元
join()
最後會回傳一個新的 string- 原本的 array 並不會被改變
如果沒有指定字元的話,預設就會是「每個元素直接連接在一起」var arr = [7, 8, 9] console.log(arr.join('!')) // output: 7!8!9
var arr = [7, 8, 9] console.log(arr.join('')) // output: 789
map()
map()
傳入函式
第一種寫法:
在 map()
小括號裡面傳入一個函式
然後 map()
就會把「原本陣列的每一個元素」當作參數,按照順序傳進這個 double
函式裡面,用「double
函式每一次的回傳值」產生另一個新的陣列
map()
最後會回傳另一個新的 array- 原本的 array 並不會被改變
var arr = [7, 8, 9]
function double(x){
return x * 2
}
console.log(arr.map(double))
// output: [ 14, 16, 18 ]
map()
傳入匿名函式
這是第二種寫法:
也可以在 map()
的小括號裡面,直接傳入一個匿名函式
var arr = [7, 8, 9]
console.log(arr.map(function (x) {
return x * 2
}))
// output: [ 14, 16, 18 ]
map()
再接 map()
map()
後面可以接無限多個 map()
- 第一次
map()
:對arr
陣列的每個元素執行x * 2
- 第二次
map()
:用第一次map()
回傳的新陣列,再針對新陣列的每個元素執行x * -1
var arr = [7, 8, 9]
console.log(
arr
.map(function (x) {
return x * 2
})
.map(function(x){
return x * -1
})
)
// output: [ -14, -16, -18 ]
filter()
過濾東西
filter()
可以把東西過濾掉:回傳 true 的東西會留下,回傳 false 的東西會不見
filter()
最後會回傳另一個新的 array- 原本的 array 並不會被改變
把 arr
陣列的每個元素當作參數,按照順序傳進 filter()
的函式裡面
x > 0
回傳是 true 的元素就會留下x > 0
回傳是 false 的元素就會不見
var arr = [7, -8, 9, 2, -5, 3]
console.log(
arr
.map(function(x) {
return x * 2
})
.filter(function(x) {
return x > 0
})
)
// output: [ 14, 18, 4, 6 ]
因為 map()
和 filter()
最後都是回傳一個 array,所以 map()
和 filter()
都可以互相接連使用
例如:
var arr = [7, -8, 9, 2, -5, 3]
console.log(
arr
.map(function (x) {
return x * 2
})
.filter(function (x) {
return x > 0
})
.map(function(x){
return x - 1
})
)
// output: [ 13, 17, 3, 5 ]
注意!因為 join()
最後會回傳的是一個「string」,所以後面就不能再接 map()
或 filter()
原因:string 並沒有 map()
或 filter()
這些函式可以用,所以就會出錯
slice()
擷取陣列的某個部份
slice()
會回傳另一個新的 array- 原本的 array 並不會被改變
只傳入一個參數
arr.slice(2)
代表:從 arr
陣列的「第 2 個 index 的元素」開始擷取,到最後一個元素我都要
var arr = ['milk', 'biscuit', 'salmon', 'mango', 'noodle']
console.log(arr.slice(2))
// output: [ 'salmon', 'mango', 'noodle' ]
傳入兩個參數
[範例一]
arr.slice(2, 4)
的意思是:
- 第一個參數:我要從「第 2 個 index 的元素」開始擷取
- 第二個參數:我要切到第 4 個,但是第 4 個我不要
所以,就只會擷取 index 是 2, 3 的元素
var arr = ['milk', 'biscuit', 'salmon', 'mango', 'noodle']
console.log(arr.slice(2, 4))
// output: [ 'salmon', 'mango' ]
[範例二]
arr.slice(1, 5)
只會擷取 index 是 1, 2, 3, 4 的元素
var arr = ['milk', 'biscuit', 'salmon', 'mango', 'noodle']
console.log(arr.slice(1, 5))
// output: [ 'biscuit', 'salmon', 'mango', 'noodle' ]
splice()
插入、替換元素
splice 是「拼接」的意思
splice()
可以做到兩件事情:
- 插入元素
- 替換元素
splice()
會直接改變原本的 array
例如:
原本的 months
陣列是 ['Jan', 'March', 'April', 'June']
- 第一次
months.splice(1, 0, 'Feb')
:會在 index = 1 的位置用 'Feb' 來「取代 0 個元素」
這時,months
陣列就會變成 ['Jan', 'Feb', 'March', 'April', 'June']
- 第二次
months.splice(4, 1, 'May')
:會在 index = 4 的位置用 'May'「取代 1 個元素」
最後,months
陣列就會變成 ['Jan', 'Feb', 'March', 'April', 'May']
var months = ['Jan', 'March', 'April', 'June']
months.splice(1, 0, 'Feb')
// replaces 0 element at index 1
console.log(months)
// output: [ 'Jan', 'Feb', 'March', 'April', 'June' ]
months.splice(4, 1, 'May')
// replaces 1 element at index 4
console.log(months)
// output: [ 'Jan', 'Feb', 'March', 'April', 'May' ]
sort()
排序
sort()
會直接改變原本的 array- 是按照「字典序」(字典裡的順序)來排序的
字母
如果是字母的話,就會根據「每個元素的第一個字母」,按照字母的排序(a, b, c...),去重新排序 array 裡的元素
如果第一個字母相同,就比第二個字母
數字
如果是數字的話,不是按照「數字大小」排列,而是會把數字當作「字串」排列,所以是按照「每個元素的第一個數字」的字典序來排序
如果第一個數字相同,就比第二個數字
var animals = ['elephant', 'dog', 'ant', 'cat', 'bird', 'alpaca']
animals.sort()
console.log(animals)
// output: [ 'alpaca', 'ant', 'bird', 'cat', 'dog', 'elephant' ]
var arr = [5, 100000, 1, 25, 9, 213]
arr.sort()
console.log(arr)
// output: [ 1, 100000, 213, 25, 5, 9 ]
讓數字由小到大排列
如果想要讓數字由小到大排列,可以這麼做:
在 sort()
小括號傳入一個 compareFunction
,用這個 function 來告訴 sort()
要怎麼排序
這個 function 會傳入 a, b 這兩個數字當作參數,「由小到大排列」的規則如下:
- 如果
a === b
,就 return 0 - 如果
a < b
,也就是「a, b 不用互換位置」,就 return 一個負數 - 如果
a > b
,也就是「a, b 要互換位置」,就 return 一個正數
最後,把 arr
陣列印出來,就會是我想要的結果了:由小到大排列
var arr = [5, 100000, 1, 25, 9, 213]
// 由小到大排列
arr.sort(function(a, b){
if(a === b) return 0
if(a < b) return -1
return 1
})
console.log(arr)
// output: [ 1, 5, 9, 25, 213, 100000 ]
讓數字由大到小排列
這個 function 會傳入 a, b 這兩個數字當作參數,「由大到小排列」的規則如下:
- 如果
a === b
,就 return 0 - 如果
a > b
,也就是「a, b 不用互換位置」,就 return 一個負數 - 如果
a < b
,也就是「a, b 要互換位置」,就 return 一個正數
最後,把 arr
陣列印出來,就會是我想要的結果了:由大到小排列
var arr = [5, 100000, 1, 25, 9, 213]
// 由大到小排列
arr.sort(function(a, b){
if(a === b) return 0
if(a > b) return -1
return 1
})
console.log(arr)
// output: [ 100000, 213, 25, 9, 5, 1 ]
用三元運算子來寫「由大到小排列」
var arr = [5, 100000, 1, 25, 9, 213]
// 由大到小排列
arr.sort(function(a, b){
if(a === b) return 0
return (a > b) ? -1 : 1
})
console.log(arr)
// output: [ 100000, 213, 25, 9, 5, 1 ]
用數學的角度去想
前面講解完原理之後,之後寫題目就直接用a - b
或 b - a
這樣寫即可
「由大到小」排列 return b - a
重點!用一個正確的排序來做假設,會比較容易想。例如 a = 5, b = 1
就是「由大到小」排列
假設 a = 5, b = 1
因為是要「由大到小」排列,所以 a, b 不用換位置--> 就要回傳一個負數,所以要讓 b - a
var arr = [5, 100000, 1, 25, 9, 213]
// 由大到小排列
arr.sort(function(a, b){
return b - a
})
console.log(arr)
// output: [ 100000, 213, 25, 9, 5, 1 ]
「由小到大」排列 return a - b
重點!用一個正確的排序來做假設,會比較容易想。例如 a = 1, b = 5
就是「由小到大」排列
假設 a = 1, b = 5
因為是要「由小到大」排列,所以 a, b 不用換位置--> 就要回傳一個負數,所以要讓 a - b
var arr = [5, 100000, 1, 25, 9, 213]
// 由小到大排列
arr.sort(function(a, b){
return a - b
})
console.log(arr)
// output: [ 1, 5, 9, 25, 213, 100000 ]
reduce()
reduce()
的小括號裡面,可以傳入兩個參數
[6, 7, 8, 9].reduce(function (accumulator, currentValue) {
return currentValue + accumulator
}, 35)
reduce()
第一個參數:是一個 function
reduce()
一定要傳入一個 function
reduce()
所傳入的 function 會有兩個參數:
- 第一個參數
accumulator
:就是「累積器」的意思
--> 這次 return 回來的值,就會是下一次的accumulator
- 第二個參數
currentValue
:就是「陣列裡面的每一個元素」
reduce()
最後 return 的值,就是「accumulator
最終的值」
reduce()
第二個參數 initialValue
: 會是 accumulator
的初始值
initialValue
可加可不加
如果沒有設定 initialValue
:
- 「陣列的第一個元素」就會是「
accumulator
的初始值」 - 「陣列的第二個元素」就會是「第一個
currentValue
」
reduce()
是怎麼運作的?
情況一:沒有設定 initialValue
var sum = [6, 7, 8, 9].reduce(function (accumulator, currentValue) {
return currentValue + accumulator
})
console.log(sum)
// output: 30
陣列 [6, 7, 8, 9]
有 4 個元素,所以 reduce()
小括號裡的 function 總共會執行 3 次
第 1 次:
accumulator
的初始值會是 6 (陣列的第一個元素)currentValue
會是 7 (陣列的第二個元素)- return 的值會是 6 + 7 = 13
第 2 次:
accumulator
會是 13,因為上一次 return 的值 = 13currentValue
會是 8- return 的值會是 13 + 8 = 21
第 3 次:
accumulator
會是 21,因為上一次 return 的值 = 21currentValue
會是 9- return 的值會是 21 + 9 = 30
最後,accumulator
會是 30,所以最後 return 的值就是 30
情況二:有設定 initialValue
(會成為 accumulator
的初始值)
var sum = [6, 7, 8, 9].reduce(function (accumulator, currentValue) {
return currentValue + accumulator
}, 35)
console.log(sum)
// output: 65
陣列 [6, 7, 8, 9]
有 4 個元素,但是因為這次有設定初始值,所以 reduce()
小括號裡的 function 總共會執行 4 次
第 1 次:
accumulator
的初始值會是 35 (也就是我設定的initialValue
)currentValue
會是 6 (陣列的第一個元素)- return 的值會是 35 + 6 = 41
第 2 次:
accumulator
會是 41,因為上一次 return 的值 = 41currentValue
會是 7- return 的值會是 41 + 7 = 48
第 3 次:
accumulator
會是 48,因為上一次 return 的值 = 48currentValue
會是 8- return 的值會是 48 + 8 = 56
第 4 次:
accumulator
會是 56,因為上一次 return 的值 = 56currentValue
會是 9- return 的值會是 56 + 9 = 65
最後,accumulator
會是 65,所以最後 return 的值就是 65
用 reduce()
的好處是什麼?如果是用 map()
或 forEach()
會有什麼壞處呢?
請參考 這篇