以下是個人在工作中收藏總結的一些關于javascript數組方法reduce
的相關代碼片段,后續遇到其他使用這個函數的場景,將會陸續添加,這里作為備忘。
javascript數組那么多方法,為什么我要單挑reduce
方法,一個原因是我對這個方法掌握不夠,不能夠用到隨心所欲。另一個方面,我也感覺到了這個方法的龐大魅力,在許多的場景中發揮著神奇的作用。
理解reduce
函數
reduce() 方法接收一個函數作為累加器(accumulator),數組中的每個值(從左到右)開始縮減,最終為一個值。
arr.reduce([callback, initialValue])
看如下例子:
let arr = [1, 2, 3, 4, 5];// 10代表初始值,p代表每一次的累加值,在第一次為10// 如果不存在初始值,那么p第一次值為1// 此時累加的結果為15let sum = arr.reduce((p, c) => p + c, 10); // 25// 轉成es5的寫法即為:var sum = arr.reduce(function(p, c) { console.log(p); return p + c;}, 10);
片段一:字母游戲
const anagrams = str => { if (str.length <= 2) { return str.length === 2 ? [str, str[1] + str[0]] : str; } return str.split("").reduce((acc, letter, i) => { return acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)); }, []);}anagrams("abc"); // 結果會是什么呢?
reduce
負責篩選出每一次執行的首字母,遞歸負責對剩下字母的排列組合。
片段二:累加器
const sum = arr => arr.reduce((acc, val) => acc + val, 0);sum([1, 2, 3]);
片段三:計數器
const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0);countOccurrences([1, 2, 3, 2, 2, 5, 1], 1);
循環數組,每遇到一個值與給定值相等,即加1,同時將加上之后的結果作為下次的初始值。
片段四:函數柯里化
函數柯里化的目的就是為了儲存數據,然后在最后一步執行。
const curry = (fn, arity = fn.length, ...args) => arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args);curry(Math.pow)(2)(10);curry(Math.min, 3)(10)(50)(2);
通過判斷函數的參數取得當前函數的length
(當然也可以自己指定),如果所傳的參數比當前參數少,則繼續遞歸下面,同時儲存上一次傳遞的參數。
片段五:數組扁平化
const deepFlatten = arr => arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []);deepFlatten([1, [2, [3, 4, [5, 6]]]]);
片段六:生成菲波列契數組
const fibonacci = n => Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []);fibonacci(5);
片段七:管道加工器
const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg);pipe(btoa, x => x.toUpperCase())("Test");
通過對傳遞的參數進行函數加工,之后將加工之后的數據作為下一個函數的參數,這樣層層傳遞下去。
片段八:中間件
const dispatch = action => { console.log('action', action); return action;}const middleware1 = dispatch => { return action => { console.log("middleware1"); const result = dispatch(action); console.log("after middleware1"); return result; }}const middleware2 = dispatch => { return action => { console.log("middleware2"); const result = dispatch(action); console.log("after middleware2"); return result; }}const middleware3 = dispatch => { return action => { console.log("middleware3"); const result = dispatch(action); console.log("after middleware3"); return result; }}const compose = middlewares => middlewares.reduce((a, b) => args => a(b(args)))const middlewares = [middleware1, middleware2, middleware3];const afterDispatch = compose(middlewares)(dispatch);const testAction = arg => { return { type: "TEST_ACTION", params: arg };};afterDispatch(testAction("1111"));
redux
中經典的compose
函數中運用了這種方式,通過對中間件的重重層疊,在真正發起action的時候觸發函數執行。新聞熱點
疑難解答