数组的reduce深解

数组—reduce

数组的reduce方法和迭代方法(map、forEach、filter…)一样,都会对数组进行遍历,reduce的第一个参数得到的是计算后的效果。

这个方法接受两个参数:

  • 要执行的函数,要执行的函数可传入四个参数,分别是:
    1. prev: 上次调用函数的返回值;
    2. cur: 当前元素;
    3. index: 当前元素索引;
    4. arr: 被遍历的数组。
  • 函数迭代的初始值
let arr = [1, 2, 3, 4];
let sum = arr.reduce(function(prev, cur, index, arr) {
    console.log(prev, cur, index);
    return prev + cur;
})
console.log(arr, sum);

打印结果:
打印结果
设置初始值:

let arr = [1, 2, 3, 4];
let sum = arr.reduce(function(prev, cur, index, arr) {
    console.log(prev, cur, index);
    return prev + cur;
},5)
console.log(arr, sum);

打印结果:
打印结果

地阶操作:

求和+乘积算法的应用

let arr = [1,2,3,4,5]
console.log(arr.reduce((p,c) => p + c))//15
console.log(arr.reduce((p,c) => a * b))//120

天阶操作:

一. 计算数组中每个元素出现的次数

let arr = ['茜茜','浩浩','小茜','茜茜','小浩','茜茜','浩浩'] 

let arrResult = arr.reduce((pre,cur) =>{
    if(cur in pre){
        pre[cur]++
    }else{
        pre[cur] = 1
    }
    return pre
},{})

console.log(arrResult)//结果:{茜茜: 3, 浩浩: 2, 小茜: 1, 小浩: 1}

二. 数组去重

let arrResult = arr.reduce((pre,cur) =>{
    if(!pre.includes(cur)){
        pre.push(cur)
    }
    return pre;
},[])

console.log(arrResult)//结果:["茜茜", "浩浩", "小茜", "小浩"]

三. 对象属性求和

let person = [
    {
        name: '茜茜',
        age: 18
    },{
        name: '浩浩',
        age: 16
    },{
        name: '浩茜',
        age: 20
    }
]

let result = person.reduce((p,c) =>{
    p = p + c.age;
    return p;
},0)

console.log(result)//结果:54

天外天操作

一. 多维数组将一维数组

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]

二. 数组和对象深克隆

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
}

三. 封装同步顺序执行函数并返回结果

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)

四. (三进阶)封装异步请求顺序执行,并处理请求结果

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)
// 应该在then函数中定义onResolve和onRejct函数,如果使用catch捕获错误,会进入下一次事件循环,不是同步执行;此处如果需要异步执行,请自行修改

五. 模拟koa洋葱模型

// 每个中间件都能接收到core
function receiveMiddleware(middlewareList) {
    //将中间件队列改造为函数层层嵌套形式
    //[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('验证csrf Token')

    next(lastMDarg)

    console.log('验证csrf Token end')
}

const VerfiyAuth = next => lastMDarg => {
    console.log('验证是否登录')

    next(lastMDarg)

    console.log('验证是否登录 end')
}

const VerfiyRoutes = next => lastMDarg => {
    console.log('验证路由匹配')

    next(lastMDarg)

    console.log('验证路由匹配 end')
}
let dispatch = receiveMiddleware([VerfiyCsrfToekn, VerfiyAuth, VerfiyRoutes])
dispatch()

六. 带异步控制的中间件

const store = {
    status: { name: '固态空气' },
    getState: () => {
        return this.status
    },
    dispatch: arg => {
        console.log(`我是核心操作,参数=${arg}`)
    }
}

function receiveMiddleware(middlewareList) {
    //拿到中间件队列
    let dispatch = store.dispatch
    let middlewareAPI = {
        dispatch: arg => {
            dispatch(arg)
        },
        getState: store.getState
    }

    //判断中间件数量
    if (middlewareList.length === 0) {
        return dispatch
    }
    //将核心操作当作参数赋予每个中间件
    middlewareList = middlewareList.map(middleware => middleware(middlewareAPI))
    //将中间件队列改造为函数层层嵌套形式
    //[a,b,c,d] => a(b(c(d(core)))) By reduce
    let tiggerPipe = middlewareList.reduce((prev, cur) => reallyDispatch => prev(cur(reallyDispatch)))

    //重写dispatch
    dispatch = tiggerPipe(store.dispatch)
    return dispatch
}

const VerfiyCsrfToekn = middlewareAPI => next => lastMDarg => {
    console.log('验证csrf Token')
    next(lastMDarg)
    console.log('验证csrf Token end')
}

const VerfiyAuth = middlewareAPI => next => lastMDarg => {
    console.log('验证是否登录')
    next(lastMDarg)
    console.log('验证是否登录 end')
}

const VerfiyRoutes = middlewareAPI => next => lastMDarg => {
    console.log('验证路由匹配')
    next(lastMDarg)
    console.log('验证路由匹配 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 = '我是固态空气'
        middlewareAPI.dispatch(test)
        console.log(middlewareAPI.getState())
    }, 3000)
}

dispatch(asyncFun)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值