JS Array.prototype.reduce的一些理解
Array.prototype.reduce在以前用的不多,在位元組跳動面試的時候問到了這個問題,後面就去看了下MDN,稍微對它理解了些
用法
reduce
方法將陣列從左到右的每個元素依次傳入回撥函式
:point_down:是些常用到的地方
統計字串中每個字元出現的次數
方法1(這種方法是我沒接觸Array.prototype.reduce最常用的方法):
const str = '9kFZTQLbUWOjurz9IKRdeg28rYxULHWDUrIHxCY6tnHleoJ' const obj = {} str.split('').forEach(item => { obj[item] ? obj[item]++ : obj[item] = 1 }) 複製程式碼
方法2(這個好玩一點點):
const str = '9kFZTQLbUWOjurz9IKRdeg28rYxULHWDUrIHxCY6tnHleoJ' const obj = {} Array.from(str).reduce((accumulator, current) => { current in accumulator ? accumulator[current]++ : accumulator[current] = 1 return accumulator }, obj) 複製程式碼
嗯,方法2雖然步驟比方法1複雜些(其實並不複雜吼),但是是不是更好玩些:wink:?
篩選陣列中同時滿足多個條件的資料
方法1(常用):
const arr = [ { "name": "a1111", "age": 25 }, { "name": "a1", "age": 26 }, { "name": "a11", "age": 27 }, { "name": "a", "age": 29 }, { "name": "a11", "age": 29 }, { "name": "a11", "age": 26 }, { "name": "a111", "age": 25 }, { "name": "a11", "age": 26 }, { "name": "a1", "age": 26 }, { "name": "a", "age": 26 } ] arr.filter(item => item.name.length === 3) .filter(item => item.age > 26) /* [ { "name": "a11", "age": 27 }, { "name": "a11", "age": 29 } ] */ 複製程式碼
方法2(reduce方法):
const arr = [ { "name": "a1111", "age": 25 }, { "name": "a1", "age": 26 }, { "name": "a11", "age": 27 }, { "name": "a", "age": 29 }, { "name": "a11", "age": 29 }, { "name": "a11", "age": 26 }, { "name": "a111", "age": 25 }, { "name": "a11", "age": 26 }, { "name": "a1", "age": 26 }, { "name": "a", "age": 26 } ] const filter1 = (item) => item.name.length === 3 const filter2 = (item) => item.age > 26 [ filter1, filter2 ].reduce((accumulator, fn) => { return fn(accumulator) }, arr) /* [ { "name": "a11", "age": 27 }, { "name": "a11", "age": 29 } ] */ 複製程式碼
用了這個方法,那我們試試看用for迴圈來實現Array.prortotype.reduce
先看看reduce接收的引數:
arr.reduce(callback[, initialValue]) 複製程式碼
reduce方法接收1個callback
的函式作為第一個引數,還有1個可選引數initialValue
。
同時callback
函式有最多4個引數
- accumulator 累加器累加回調的返回值;它是在最後一次呼叫回撥時返回的累計值。如果提供了initialValue,它的預設值就是initialValue,否則就是陣列的第一個值
- currentValue 當前參與計算的元素
- currentIndex 當前參與計算的元素的陣列下標
- array 當前參與運算的陣列
知道了這些,那我們實現reduce方法就很簡單了
Array.prototype.selfReduce = function() { const ary = this const { length } = ary if (arguments.length === 0) { throw new TypeError('undefined is not a function') } if (typeof arguments[0] !== 'function') { throw new TypeError(arguments[0] + 'is not a function') } if (ary.length === 0 && arguments.length === 1) { throw new TypeError('Reduce of empty array with no initial value') } const callback = arguments[0] const startIndex = arguments.length >= 2 ? 0 : 1 let value = startIndex === 0 ? arguments[1] : ary[0] for (let i = startIndex; i < length; i++) { value = callback(value, ary[i], i, ary) } return value } 複製程式碼
同時,reduce
還有個兄弟:two_men_holding_hands:reduceRight
,reduceRight如其名,是將陣列從右到左的將每個元素傳入callback
函式。那實現reduceRight
實現起來也就簡單了。
Array.prototype.selfReduceRight = function () { const ary = this const { length } = ary if (arguments.length === 0) { throw new TypeError('undefined is not a function') } if (typeof arguments[0] !== 'function') { throw new TypeError(arguments[0] + 'is not a function') } if (ary.length === 0 && arguments.length === 1) { throw new TypeError('Reduce of empty array with no initial value') } const startIndex = arguments.length >= 2 ? length - 1 : length - 2 const callback = arguments[0] let value = startIndex === 0 ? arguments[1] : ary[length - 1] for (let i = startIndex; i >= 0; i--) { value = callback(value, ary[i], i, ary) } return value } 複製程式碼
嗯,這篇文章就寫完了,也不知道寫了些什麼,在掘金寫文章不多,所以不知道各位看官的口味,如果文章有寫的不對或者寫的不好的地方,煩請各位看官指出,我也好改正:pray:。