由於用for循環被老大鄙視以後,這幾天都在偷偷摸摸的研究數組的那幾個迭代方法。使用下來,感受確實妙用無窮,彷彿本身的逼格在無形中變得高大了一點點,哈哈,上一篇文章的簡單介紹確實有點糙,所以決定從新一些總結文章。面試
這篇文章就是專門總結reduce方法的,這個方法大有可研究的地方,值得你們get它並去同手實踐一下。segmentfault
上一篇文章我認爲reduce是一個聚合或者減小方法,它能夠將數組中的每一項經過疊加變成一項,可是其實這種說法彷佛不太準確。先無論這個,咱們來看看例子再說。數組
從最簡單的例子開始。瀏覽器
var arr = [1, 2, 3, 4, 5]; sum = arr.reduce(function(prev, cur, index, arr) { console.log(prevres, cur, index); return prevres + cur; }) console.log(arr, sum);
輸出結果函數
1 2 1 3 3 2 6 4 3 10 5 4 [1, 2, 3, 4, 5] 15
咱們先從新回顧一下reduce中回調函數的參數,這個回調函數中有4個參數,意思分別爲spa
prev: 第一項的值或者上一次疊加的結果值
cur: 當前會參與疊加的項
index: 當前值的索引
arr: 數組自己code
首先咱們要區分prev與cur這2個參數的區別,剛開始的時候我覺得他們是一種類型的,但是後來我發現我理解錯了。prev表示每次疊加以後的結果,類型可能與數組中的每一項不一樣,而cur則表示數組中參與疊加的當前項。在後邊咱們能夠結合實例來理解這個地方。對象
其次咱們看到,上例中其實值遍歷了4次,數組有五項。數組中的第一項被當作了prev的初始值,而遍歷從第二項開始。索引
咱們看下面一個例子。ip
某同窗的期末成績以下表示
var result = [ { subject: 'math', score: 88 }, { subject: 'chinese', score: 95 }, { subject: 'english', score: 80 } ];
如何求該同窗的總成績?
很顯然,利用for循環能夠很簡單得出結論
var sum = 0; for(var i=0; i<result.length; i++) { sum += result[i].score; }
可是咱們的宗旨就是拋棄for循環,所以使用reduce來搞定這個問題
var sum = result.reduce(function(prev, cur) { return cur.score + prev; }, 0);
這個時候,我給reduce參數添加了第二個參數。經過打印我發現設置了這個參數以後,reduce遍歷便已經從第一項開始了。
這第二個參數就是設置prev的初始類型和初始值,好比爲0,就表示prev的初始值爲number類型,值爲0,所以,reduce的最終結果也會是number類型。
由於第二個參數爲累計結果的初始值,所以假設該同窗由於違紀被處罰在總成績總扣10分,只須要將初始值設置爲-10便可。
var sum = result.reduce(function(prev, cur) { return cur.score + prev; }, -10);
咱們來給這個例子增長一點難度。假如該同窗的總成績中,各科所佔的比重不一樣,分別爲50%,30%,20%,咱們應該如何求出最終的權重結果呢?
解決方案以下:
var dis = { math: 0.5, chinese: 0.3, english: 0.2 } var sum = result.reduce(function(prev, cur) { console.log(prev); return cur.score + prev; }, -10); var qsum = result.reduce(function(prev, cur) { return prev + cur.score * dis[cur.subject] }, 0) console.log(sum, qsum);
爲了計算出權重以後的總值,咱們在回調函數內部修改了數組當前項,是使他和權重比例關聯襲來,並從新返回一個同樣的回調函數,將新修改的當前項傳入,就和以前的例子是同樣的了。
在segmentfault上看到一個面試題,問如何知道一串字符串中每一個字母出現的次數?
咱們能夠運用reduce來解決這個問題。
咱們在reduce的第二個參數裏面初始了回調函數第一個參數的類型和值,將字符串轉化爲數組,那麼迭代的結果將是一個對象,對象的每一項key值就是字符串的字母。運行感覺一下吧。
var arrString = 'abcdaabc'; arrString.split('').reduce(function(res, cur) { res[cur] ? res[cur] ++ : res[cur] = 1 return res; }, {})
因爲能夠經過第二參數設置疊加結果的類型初始值,所以這個時候reduce就再也不僅僅只是作一個加法了,咱們能夠靈活的運用它來進行各類各樣的類型轉換,好比將數組按照必定規則轉換爲對象,也能夠將一種形式的數組轉換爲另外一種形式的數組,你們能夠動手去嘗試同樣。
[1, 2].reduce(function(res, cur) { res.push(cur + 1); return res; }, [])
這種特性使得reduce在實際開發中大有可爲!可是須要注意點,在ie9一下的瀏覽器中,並不支持該方法 !