您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)js數(shù)組方法reduce怎么用的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
javascript數(shù)組那么多方法,為什么我要單挑reduce
方法,一個原因是我對這個方法掌握不夠,不能夠用到隨心所欲。另一個方面,我也感覺到了這個方法的龐大魅力,在許多的場景中發(fā)揮著神奇的作用。
理解reduce
函數(shù)
reduce() 方法接收一個函數(shù)作為累加器(accumulator),數(shù)組中的每個值(從左到右)開始縮減,最終為一個值。
arr.reduce([callback, initialValue])
看如下例子:
let arr = [1, 2, 3, 4, 5]; // 10代表初始值,p代表每一次的累加值,在第一次為10 // 如果不存在初始值,那么p第一次值為1 // 此時累加的結(jié)果為15 let sum = arr.reduce((p, c) => p + c, 10); // 25 // 轉(zhuǎn)成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"); // 結(jié)果會是什么呢?
reduce
負責(zé)篩選出每一次執(zhí)行的首字母,遞歸負責(zé)對剩下字母的排列組合。
片段二:累加器
const sum = arr => arr.reduce((acc, val) => acc + val, 0); sum([1, 2, 3]);
片段三:計數(shù)器
const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); countOccurrences([1, 2, 3, 2, 2, 5, 1], 1);
循環(huán)數(shù)組,每遇到一個值與給定值相等,即加1,同時將加上之后的結(jié)果作為下次的初始值。
片段四:函數(shù)柯里化
函數(shù)柯里化的目的就是為了儲存數(shù)據(jù),然后在最后一步執(zhí)行。
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);
通過判斷函數(shù)的參數(shù)取得當前函數(shù)的length
(當然也可以自己指定),如果所傳的參數(shù)比當前參數(shù)少,則繼續(xù)遞歸下面,同時儲存上一次傳遞的參數(shù)。
片段五:數(shù)組扁平化
const deepFlatten = arr => arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []); deepFlatten([1, [2, [3, 4, [5, 6]]]]);
片段六:生成菲波列契數(shù)組
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");
通過對傳遞的參數(shù)進行函數(shù)加工,之后將加工之后的數(shù)據(jù)作為下一個函數(shù)的參數(shù),這樣層層傳遞下去。
片段八:中間件
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
中經(jīng)典的compose
函數(shù)中運用了這種方式,通過對中間件的重重層疊,在真正發(fā)起action的時候觸發(fā)函數(shù)執(zhí)行。
片段九:redux-actions對state的加工片段
// redux-actions/src/handleAction.js const handleAction = (type, reducer, defaultState) => { const types = type.toString(); const [nextReducer, throwReducer] = [reducer, reducer]; return (state = defaultState, action) => { const { type: actionType } = action; if (!actionType || types.indexOf(actionType.toString()) === -1) { return state; } return (action.error === true ? throwReducer : nextReducer)(state, action); } } // reduce-reducers/src/index.js const reduceReducer = (...reducers) => { return (previous, current) => { reducers.reduce((p, r) => r(p, current), previous); } } // redux-actions/src/handleActions.js const handleActions = (handlers, defaultState, { namespace } = {}) => { // reducers的扁平化 const flattenedReducerMap = flattenReducerMap(handles, namespace); // 每一種ACTION下對應(yīng)的reducer處理方式 const reducers = Reflect.ownkeys(flattenedReducerMap).map(type => handleAction( type, flattenedReducerMap[type], defaultState )); // 狀態(tài)的加工器,用于對reducer的執(zhí)行 const reducer = reduceReducers(...reducers); // reducer觸發(fā) return (state = defaultState, action) => reducer(state, action); }
片段十:數(shù)據(jù)加工器
const reducers = { totalInEuros: (state, item) => { return state.euros += item.price * 0.897424392; }, totalInYen: (state, item) => { return state.yens += item.price * 113.852; } }; const manageReducers = reducers => { return (state, item) => { return Object.keys(reducers).reduce((nextState, key) => { reducers[key](state, item); return state; }, {}) } } const bigTotalPriceReducer = manageReducers(reducers); const initialState = { euros: 0, yens: 0 }; const items = [{ price: 10 }, { price: 120 }, { price: 1000 }]; const totals = items.reduce(bigTotalPriceReducer, initialState);
片段十一:對象空值判斷
let school = { name: 'Hope middle school', created: '2001', classes: [ { name: '三年二班', teachers: [ { name: '張二蛋', age: 26, sex: '男', actor: '班主任' }, { name: '王小妞', age: 23, sex: '女', actor: '英語老師' } ] }, { name: '明星班', teachers: [ { name: '歐陽娜娜', age: 29, sex: '女', actor: '班主任' }, { name: '李易峰', age: 28, sex: '男', actor: '體育老師' }, { name: '楊冪', age: 111, sex: '女', actor: '藝術(shù)老師' } ] } ] }; // 常規(guī)做法 school.classes && school.classes[0] && school.classes[0].teachers && school.classes[0].teachers[0] && school.classes[0].teachers[0].name // reduce方法 const get = (p, o) => p.reduce((xs, x) => (xs && xs[x] ? xs[x] : null), o); get(['classes', 0, 'teachers', 0, 'name'], school); // 張二蛋
片段十二:分組
const groupBy = (arr, func) => arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc, val, i) => { acc[val] = (acc[val] || []).concat(arr[i]); return acc; }, {}); groupBy([6.1, 4.2, 6.3], Math.floor); groupBy(['one', 'two', 'three'], 'length');
首先通過map
計算出所有的鍵值,然后再根據(jù)建值進行歸類
片段十三:對象過濾
const pick = (obj, arr) => arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {});
根據(jù)給出的鍵值來遍歷,比較對象中是否存在相同鍵值的的值,然后通過逗號表達式把賦值后的對象賦給下一個的初始值
片段十四:數(shù)組中刪除指定位置的值
const remove = (arr, func) => Array.isArray(arr) ? arr.filter(func).reduce((acc, val) => { arr.splice(arr.indexOf(val), 1); return acc.concat(val); }, []) : []; const arr = [1, 2, 3, 4]; remove(arr, n => n % 2 == 0);
首先根據(jù)filter
函數(shù)過濾出數(shù)組中符合條件的值,然后使用reduce
在原數(shù)組中刪除符合條件的值,可以得出最后arr的值變成了[1, 3]
片段十五:promise按照順序執(zhí)行
const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); const delay = d => new Promise(r => setTimeout(r, d)); const print = args => new Promise(r => r(args)); runPromisesInSeries([() => delay(1000), () => delay(2000), () => print('hello')]);
片段十六:排序
const orderBy = (arr, props, orders) => [...arr].sort((a, b) => props.reduce((acc, prop, i) => { if (acc === 0) { const [p1, p2] = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]]; acc = p1 > p2 ? 1 : p1 < p2 ? -1 : 0; } return acc; }, 0) ); const users = [{ name: 'fred', age: 48 }, { name: 'barney', age: 36 }, { name: 'fly', age: 26 }]; orderBy(users, ['name', 'age'], ['asc', 'desc']); orderBy(users, ['name', 'age']);
片段十七:選擇
const select = (from, selector) => selector.split('.').reduce((prev, cur) => prev && prev[cur], from); const obj = { selector: { to: { val: 'val to select' } } }; select(obj, 'selector.to.val');
感謝各位的閱讀!關(guān)于“js數(shù)組方法reduce怎么用”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。