日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

js reduce实现中间件_js数组高阶方法reduce经典用法代码分享

發布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js reduce实现中间件_js数组高阶方法reduce经典用法代码分享 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

以下是個人在工作中收藏總結的一些關于javascript數組方法reduce的相關代碼片段,后續遇到其他使用這個函數的場景,將會陸續添加,這里作為備忘。

javascript數組那么多方法,為什么我要單挑reduce方法,一個原因是我對這個方法掌握不夠,不能夠用到隨心所欲。另一個方面,我也感覺到了這個方法的龐大魅力,在許多的場景中發揮著神奇的作用。

理解reduce函數

reduce() 方法接收一個函數作為累加器(accumulator),數組中的每個值(從左到右)開始縮減,最終為一個值。

arr.reduce([callback, initialValue])

看如下例子:

let arr = [1, 2, 3, 4, 5];

// 10代表初始值,p代表每一次的累加值,在第一次為10

// 如果不存在初始值,那么p第一次值為1

// 此時累加的結果為15

let 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的時候觸發函數執行。

片段九: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下對應的reducer處理方式

const reducers = Reflect.ownkeys(flattenedReducerMap).map(type => handleAction(

type,

flattenedReducerMap[type],

defaultState

));

// 狀態的加工器,用于對reducer的執行

const reducer = reduceReducers(...reducers);

// reducer觸發

return (state = defaultState, action) => reducer(state, action);

}

片段十:數據加工器

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: '藝術老師' }

]

}

]

};

// 常規做法

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計算出所有的鍵值,然后再根據建值進行歸類

片段十三:對象過濾

const pick = (obj, arr) =>

arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {});

pick({ a: 1, b: '2', c: 3 }, ['a', 'c']);

根據給出的鍵值來遍歷,比較對象中是否存在相同鍵值的的值,然后通過逗號表達式把賦值后的對象賦給下一個的初始值

片段十四:數組中刪除指定位置的值

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);

首先根據filter函數過濾出數組中符合條件的值,然后使用reduce在原數組中刪除符合條件的值,可以得出最后arr的值變成了[1, 3]

片段十五:promise按照順序執行

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');

總結

以上是生活随笔為你收集整理的js reduce实现中间件_js数组高阶方法reduce经典用法代码分享的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。