接續前一篇文章,我們繼續探討陣列的處理方式。首先我們會先處理foreach,接著將every&some一同處理 最後在探討reduce這個最不直觀的用法。
foreach()
foreach可以直接從字面上聯想,對陣列中的每個元素做加工。
聽起來很耳熟是吧?沒錯 聽起來簡直跟map一模一樣,那兩者的差別在哪?
我直接先講總結,接著會再用例子說明。
- 任何foreach能做到的事情,map都能做到
- foreach會改變原有的陣列,map則是回傳一個新陣列
- 接續上一點,foreach並不回傳任何值(undefined)
- 效能上map較為優秀
今天我們使用兩種方法,目標是對陣列的元素做*2的加工
首先是map
let arr = [1,2,4,5,8]
let usemap = arr.map(x => x*2)
console.log(usemap) // [ 2, 4, 8, 10, 16 ]
console.log(arr) // [ 1, 2, 4, 5, 8 ] 陣列沒受到影響
接著是foreach,基本語法為function(item,index,array)
let arr = [1,2,4,5,8]
let useforeach = arr.forEach((item,index) => arr[index] = item*2)
console.log(useforeach)// undefined 沒有回傳任何值。
console.log(arr) // [ 2, 4, 8, 10, 16 ]
至於是不是因為這樣就必須每次都使用map? 我想不是的,畢竟總有會需要修改原陣列的時候,還是要看時機使用。
every() & some()
兩者的區別非常簡單
every會檢視陣列內的每個元素,若每個都為true則回傳true
some同樣檢視陣列內的每個元素,但只要有一個元素為true則回傳true,只有當所有元素皆為false時才回傳false,以下我們看一下例子。
test = [90,45,67,85,20,70]
let scorecheck = test.every(item => item > 30)
console.log(scorecheck) //false
let scorecheck2 = test.some(item => item > 30)
console.log(scorecheck2) //true
reduce()
這應該是裡面最為複雜的一個了,簡單來說是讓陣列內元素做加總的方法。
首先我們先看一下語法
arr.reduce(callback[accumulator, currentValue, currentIndex, array], initialValue)
accumulator 用來累加的起始值,如果沒有設定 initialValue,就是陣列的第一個元素。
currentValue 接著要累加的元素
initialValue 初始值,可以不設定。
光看這樣一定覺得霧薩薩,一樣我們舉個例子。
let arr = [1,2,4,5,8]
arr.reduce(function(x,y){return x + y}) //20
注意到回傳的僅是一個值,整個過程分為4次
首先起始值因為沒有指定,所以由第一個元素來決定 起始值為1
第一次加總為1 + 2 總和值為3,並將3作為accumulator繼續
第二次加總為3+4 總和值為7,並將7作為accumulator繼續
第三次加總為7+5 總和值為12,並將12作為accumulator繼續
第四次加總為12+8 總和值為20,最後將20回傳。
乍看之下會覺得這種方法沒什麼用,但想像一下今天要處理的陣列如下
let newrr =[
[1,2,4,5,8],
[7,6,8,12],
[1,8,9,5]
]
像這樣的多維陣列要做加總或連結就會比較複雜一些,比方我現在要將這三個陣列串起,我就會這樣寫。
newrr.reduce(function(x,y){return x.concat(y)});
// [ 1, 2, 4, 5, 8, 7, 6, 8, 12, 1, 8, 9, 5 ]
目前對這七個方法比較有概念了,但其實資料上都還有很多進階的運用,之後應該也會再開新文章探討。
參考網站:
https://codeburst.io/javascript-map-vs-foreach-f38111822c0f
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce