reduce详解和多种用法

149 阅读2分钟

reduce详解

  • const val=arr.reduce((t,v)=>{return t+v},c)
  • 以t作为累计结果的初始值,不设置t则以数组第一个元素为初始值
  • 开始遍历,使用累计器处理v,将v的映射结果累计到t上,结束此次循环,返回
  • c初始值
  • 另外reduce还有一个胞弟reduceRight,两个方法的功能其实是一样的,只不过reduce是升序执行, reduceRight是降序执行。 对空数组调用reduce()和reduceRight()是不会执行其回调函数的,可认为reduce()对空数组无效

reduce用法

  • 求和
function Accumulation (...arr) {
    return arr.reduce((t, v) => t + v, 0)
}
console.log(Accumulation(1, 2, 3, 4, 5, 6, 7)) // 28
  • 代替reverse 降序
function reverseEv (arr = []) {
    return arr.reduceRight((t, v) => [...t, v], [])
}
console.log(reverseEv([1, 2, 3, 4, 5])) // [5,4,3,2,1]
  • 代替map和filter
function mapFilterEv () {
    const arr = [1, 2, 3, 4, 5]
    // 代替map:[2,4,6,8,10]
    const mapArr = arr.reduce((t, v) => [...t, v * 2], [])
    console.log(mapArr) // [2,4,6,8,10]
    // 代替filter: [4,5]
    const filterArr = arr.reduce((t, v) => v > 3 ? [...t, v] : t, [])
    console.log(filterArr) // [4,5]
}
mapFilterEv()
  • 代替some和every
function someEveryEv () {
    const scores = [
    { score: 45, subject: 'chinese' },
    { score: 90, subject: 'math' },
    { score: 60, subject: 'english' }
    ]
    // 代替some:至少一门合格
    const someScores = scores.reduce((t, v) => t || v.score >= 60, false)
    console.log(someScores) // true
    // 代替every:全部合格
    const every = scores.reduce((t, v) => t && v.score >= 60, true)
    console.log(every) // false
}
someEveryEv()
  • 数组分割
function chunkEv (arr = [], size = 1) {
   return arr.length
       // eslint-disable-next-line no-sequences
       ? arr.reduce((t, v) => (t[t.length - 1].length === size ? t.push([v]) : t[t.length - 1].push(v), t), [[]])
       : []
   }
console.log(chunkEv([1, 2, 3, 4, 5], 2)) // [[1,2],[3,4],[5]]
  • 数据过滤
function differenceEv (arr1 = [], arr2 = []) {
     // eslint-disable-next-line no-sequences
     return arr1.reduce((t, v) => (arr2.includes(v) ? t : t.push(v), t), [])
}
console.log(differenceEv([1, 2, 3, 4, 5], [1, 3, 6]))
  • 数组去重
function uniqEv (arr) {
    return arr.reduce((t, v) => t.includes(v) ? t : [...t, v], [])
}
console.log(uniqEv([2, 1, 5, 4, 1, 24, 5, 4, 2, 5, 6, 8, 1]))
  • 数组最大值和最小值
function maxEv (arr) {
    return arr.reduce((t, v) => t < v ? v : t)
}
function minEv (arr) {
    return arr.reduce((t, v) => t > v ? v : t)
}
console.log(maxEv([25, 65, 19, 25, 68, 35, 34, 98, 72, 32]))
console.log(minEv([25, 65, 19, 25, 68, 35, 34, 98, 72, 32]))
  • 数组成员个数统计
function countEv (arr) {
    // eslint-disable-next-line no-sequences
    return arr.reduce((t, v) => {
       const obj = (t[v] = (t[v] || 0) + 1, t)
       return obj
    }, {})
}
console.log(countEv([0, 1, 1, 2, 2, 2]))