reduce方法高級(jí)使用
原文:https://segmentfault.com/a/1190000039657107
關(guān)注公眾號(hào) 前端人,回復(fù)“加群”
添加無(wú)廣告優(yōu)質(zhì)學(xué)習(xí)群
前端小伙伴兒應(yīng)該都聽(tīng)過(guò)reduce這個(gè)數(shù)組的方法,總結(jié)一下我在開(kāi)發(fā)過(guò)程中遇到的reduce的一些好玩兒的用法
定義:
reduce() 方法對(duì)數(shù)組中的每個(gè)元素執(zhí)行一個(gè)由您提供的 reducer 函數(shù)(升序執(zhí)行),將其結(jié)果匯總為單個(gè)返回值。
reducer 函數(shù)接收4個(gè)參數(shù):
Accumulator (acc) (累計(jì)器) CurrentValue (cur) (當(dāng)前值) CurrentIndex (idx) (當(dāng)前索引) SourceArray (src) (源數(shù)組)
1、基礎(chǔ)的累加累乘
var arr = [1, 2, 3, 4];
var sum = arr.reduce((prev, cur) => prev + cur, 0)
var mul = arr.reduce((prev, cur) => prev * cur, 1)
console.log(sum); // 10
console.log(mul); // 24
2、對(duì)象內(nèi)的操作
var result = [
{
subject: 'math',
score: 10
},
{
subject: 'chinese',
score: 20
},
{
subject: 'english',
score: 30
}
];
var sum = result.reduce((prev, cur) => {
return cur.score + prev;
}, 0);
console.log(sum) //60
3、統(tǒng)計(jì)數(shù)組中元素出現(xiàn)次數(shù)
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.reduce((prev, cur)=>{
if(cur in prev){
prev[cur]++
}else{
prev[cur] = 1
}
return pre
}, {})
console.log(nameNum);
//{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
4、數(shù)組去重
let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((prev, cur)=>{
if(!prev.includes(cur)){
return prev.concat(cur)
}else{
return prev
}
}, [])
console.log(newArr);// [1, 2, 3, 4]5、多維數(shù)組降一維數(shù)組
let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
return arr.reduce((prev, cur) => prev.concat(Array.isArray(cur) ? newArr(cur) : cur), [])
}
console.log(newArr(arr));
//[0, 1, 2, 3, 4, 5, 6, 7]
6、數(shù)組和對(duì)象深克隆
const deepClone = param => {
if (typeof param !== 'object') return
if (Array.isArray(param)) {
param.reduce((prev, cur) => (cur instanceof Array ? [...prev, deepClone(cur)] : [...prev, cur]), [])
} else {
Object.entries(param).reduce(
(prev, [key, value]) => (typeof value === 'object' ? { ...prev, [key]: deepClone(value) } : { ...prev, [key]: value }),
{}
)
}
return param
}
7、封裝一個(gè)同步順序執(zhí)行函數(shù),并返回結(jié)果
let fn1 = () => {
return {
name: 'lsd',
age: 18
}
}
let fn2 = () => {
return {
name: 'lbb',
age: 19
}
}
let fn3 = () => {
return {
name: 'whh',
age: 20
}
}
let fnlist = [fn1, fn2, fn3]
let res = fnlist.reduce((prev, cur) => {
let t = cur()
if (t) {
prev.push(t)
}
return prev
}, [])
console.log(res)
8、基于7封裝異步請(qǐng)求順序執(zhí)行,并處理請(qǐng)求結(jié)果
let fn1 = () => {
return new Promise((resolve, reject) => resolve(1))
}
let fn2 = () => {
return new Promise((resolve, reject) => reject())
}
let fn3 = () => {
return new Promise((resolve, reject) => resolve(2))
}
let fnlist = [fn1, fn2, fn3]
let res = fnlist.reduce((prev, cur) => {
cur().then(
data => {
if (data) {
prev.push(data)
}
},
reason => {
prev.push('失敗')
}
)
return prev
}, [])
console.log(res)
應(yīng)該在then函數(shù)中定義onResolve和onRejct函數(shù),如果使用catch捕獲錯(cuò)誤,會(huì)進(jìn)入下一次事件循環(huán),不是同步執(zhí)行;此處如果需要異步執(zhí)行,請(qǐng)自行修改
9、模擬koa洋蔥模型
每個(gè)中間件都能接收到core
function receiveMiddleware(middlewareList) {
//將中間件隊(duì)列改造為函數(shù)層層嵌套形式
//[a,b,c,d] => a(b(c(d(core)))) By reduce
let tiggerPipe = middlewareList.reduce((a, b) => core => a(b(core)))
let tiggerPipeWitchCore = tiggerPipe(() => {
console.log('我是核心操作')
})
return tiggerPipeWitchCore
}
const VerfiyCsrfToekn = next => lastMDarg => {
console.log('驗(yàn)證csrf Token')
next(lastMDarg)
console.log('驗(yàn)證csrf Token end')
}
const VerfiyAuth = next => lastMDarg => {
console.log('驗(yàn)證是否登錄')
next(lastMDarg)
console.log('驗(yàn)證是否登錄 end')
}
const VerfiyRoutes = next => lastMDarg => {
console.log('驗(yàn)證路由匹配')
next(lastMDarg)
console.log('驗(yàn)證路由匹配 end')
}
let dispatch = receiveMiddleware([VerfiyCsrfToekn, VerfiyAuth, VerfiyRoutes])
dispatch()
10、帶異步控制的中間件
const store = {
status: { name: '固態(tài)空氣' },
getState: () => {
return this.status
},
dispatch: arg => {
console.log(`我是核心操作,參數(shù)=${arg}`)
}
}
function receiveMiddleware(middlewareList) {
//拿到中間件隊(duì)列
let dispatch = store.dispatch
let middlewareAPI = {
dispatch: arg => {
dispatch(arg)
},
getState: store.getState
}
//判斷中間件數(shù)量
if (middlewareList.length === 0) {
return dispatch
}
//將核心操作當(dāng)作參數(shù)賦予每個(gè)中間件
middlewareList = middlewareList.map(middleware => middleware(middlewareAPI))
//將中間件隊(duì)列改造為函數(shù)層層嵌套形式
//[a,b,c,d] => a(b(c(d(core)))) By reduce
let tiggerPipe = middlewareList.reduce((prev, cur) => reallyDispatch => prev(cur(reallyDispatch)))
//重寫(xiě)dispatch
dispatch = tiggerPipe(store.dispatch)
return dispatch
}
const VerfiyCsrfToekn = middlewareAPI => next => lastMDarg => {
console.log('驗(yàn)證csrf Token')
next(lastMDarg)
console.log('驗(yàn)證csrf Token end')
}
const VerfiyAuth = middlewareAPI => next => lastMDarg => {
console.log('驗(yàn)證是否登錄')
next(lastMDarg)
console.log('驗(yàn)證是否登錄 end')
}
const VerfiyRoutes = middlewareAPI => next => lastMDarg => {
console.log('驗(yàn)證路由匹配')
next(lastMDarg)
console.log('驗(yàn)證路由匹配 end')
}
const asyncMiddleware = middlewareAPI => next => lastMDarg => {
console.log('異步中間件-start')
if (typeof lastMDarg === 'function') {
lastMDarg(middlewareAPI)
} else {
next(lastMDarg)
console.log('異步中間件-end')
}
}
let dispatch = receiveMiddleware([VerfiyCsrfToekn, VerfiyAuth, VerfiyRoutes, asyncMiddleware])
let asyncFun = middlewareAPI => {
setTimeout(() => {
let test = '我是固態(tài)空氣'
middlewareAPI.dispatch(test)
console.log(middlewareAPI.getState())
}, 3000)
}
dispatch(asyncFun)
javascriptes6
回復(fù) 資料包領(lǐng)取我整理的進(jìn)階資料包回復(fù) 加群,加入前端進(jìn)階群console.log("文章點(diǎn)贊===文章點(diǎn)在看===你我都快樂(lè)")Bug離我更遠(yuǎn)了,下班離我更近了

評(píng)論
圖片
表情
