JS Array.prototype.reduce的一些理解

栏目: JavaScript · 发布时间: 6年前

内容简介:Array.prototype.reduce在以前用的不多,在字节跳动面试的时候问到了这个问题,后面就去看了下MDN,稍微对它理解了些:point_down:是些常用到的地方

Array.prototype.reduce在以前用的不多,在字节跳动面试的时候问到了这个问题,后面就去看了下MDN,稍微对它理解了些

用法

reduce 方法将数组从左到右的每个元素依次传入回调函数

:point_down:是些常用到的地方

统计字符串中每个字符出现的次数

方法1(这种方法是我没接触Array.prototype.reduce最常用的方法):

const str = '9kFZTQLbUWOjurz9IKRdeg28rYxULHWDUrIHxCY6tnHleoJ'
   const obj = {}
   str.split('').forEach(item => {
       obj[item] ? obj[item]++ : obj[item] = 1
   })
复制代码

方法2(这个好玩一点点 ):

const str = '9kFZTQLbUWOjurz9IKRdeg28rYxULHWDUrIHxCY6tnHleoJ'
  const obj = {}
  Array.from(str).reduce((accumulator, current) => {
    current in accumulator ? accumulator[current]++ : accumulator[current] = 1
    return accumulator  
  }, obj)
复制代码

嗯,方法2虽然步骤比方法1复杂些(其实并不复杂吼),但是是不是更好玩些:wink:?

筛选数组中同时满足多个条件的数据

方法1(常用):

const arr = [
      {
        "name": "a1111",
        "age": 25
      },
      {
        "name": "a1",
        "age": 26
      },
      {
        "name": "a11",
        "age": 27
      },
      {
        "name": "a",
        "age": 29
      },
      {
        "name": "a11",
        "age": 29
      },
      {
        "name": "a11",
        "age": 26
      },
      {
        "name": "a111",
        "age": 25
      },
      {
        "name": "a11",
        "age": 26
      },
      {
        "name": "a1",
        "age": 26
      },
      {
        "name": "a",
        "age": 26
      }
    ]
    
    arr.filter(item => item.name.length === 3)
       .filter(item => item.age > 26)
    /*
    [
      {
        "name": "a11",
        "age": 27
      },
      {
        "name": "a11",
        "age": 29
      }
    ]
    */
复制代码

方法2(reduce方法):

const arr = [
      {
        "name": "a1111",
        "age": 25
      },
      {
        "name": "a1",
        "age": 26
      },
      {
        "name": "a11",
        "age": 27
      },
      {
        "name": "a",
        "age": 29
      },
      {
        "name": "a11",
        "age": 29
      },
      {
        "name": "a11",
        "age": 26
      },
      {
        "name": "a111",
        "age": 25
      },
      {
        "name": "a11",
        "age": 26
      },
      {
        "name": "a1",
        "age": 26
      },
      {
        "name": "a",
        "age": 26
      }
    ]
   const filter1 = (item) => item.name.length === 3
   const filter2 = (item) => item.age > 26
   [ filter1, filter2 ].reduce((accumulator, fn) => {
     return fn(accumulator)   
   }, arr)
   /*
    [
      {
        "name": "a11",
        "age": 27
      },
      {
        "name": "a11",
        "age": 29
      }
    ]
    */
复制代码

用了这个方法,那我们试试看用for循环来实现Array.prortotype.reduce

先看看reduce接收的参数:

arr.reduce(callback[, initialValue])
复制代码

reduce方法接收1个 callback 的函数作为第一个参数,还有1个可选参数 initialValue 。 同时 callback 函数有最多4个参数

  • accumulator 累加器累加回调的返回值;它是在最后一次调用回调时返回的累计值。如果提供了initialValue,它的默认值就是initialValue,否则就是数组的第一个值
  • currentValue 当前参与计算的元素
  • currentIndex 当前参与计算的元素的数组下标
  • array 当前参与运算的数组

知道了这些,那我们实现reduce方法就很简单了

Array.prototype.selfReduce = function() {
       const ary = this
       const { length } = ary
       if (arguments.length === 0) {
         throw new TypeError('undefined is not a function')
       }
       if (typeof arguments[0] !== 'function') {
         throw new TypeError(arguments[0] + 'is not a function')
       }
       if (ary.length === 0 && arguments.length === 1) {
         throw new TypeError('Reduce of empty array with no initial value')
       }
       const callback = arguments[0]
       const startIndex = arguments.length >= 2 ? 0 : 1
       let value = startIndex === 0 ? arguments[1] : ary[0]
       for (let i = startIndex; i < length; i++) {
          value = callback(value, ary[i], i, ary)
       }
       return value
    }
复制代码

同时, reduce 还有个兄弟:two_men_holding_hands: reduceRight ,reduceRight如其名,是将数组从右到左的将每个元素传入 callback 函数。那实现 reduceRight 实现起来也就简单了。

Array.prototype.selfReduceRight = function () {
   const ary = this
   const { length } = ary
   if (arguments.length === 0) {
     throw new TypeError('undefined is not a function')
   }
   if (typeof arguments[0] !== 'function') {
     throw new TypeError(arguments[0] + 'is not a function')
   }
   if (ary.length === 0 && arguments.length === 1) {
       throw new TypeError('Reduce of empty array with no initial value')
   }
   const startIndex = arguments.length >= 2 ? length - 1 : length - 2
   const callback = arguments[0]
   let value = startIndex === 0 ? arguments[1] : ary[length - 1]
   for (let i = startIndex; i >= 0; i--) {
      value = callback(value, ary[i], i, ary)
   }
   return value
}
复制代码

嗯,这篇文章就写完了,也不知道写了些什么,在掘金写文章不多,所以不知道各位看官的口味,如果文章有写的不对或者写的不好的地方,烦请各位看官指出,我也好改正:pray:。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Spring框架高级编程

Spring框架高级编程

约翰逊 / 蒋培 / 机械工业出版社 / 2006-4 / 59.00元

Spring框架是主要的开源应用程序开发框架,它使得Java/J2EE开发更容易、效率更高。本书不仅向读者展示了Spring能做什么?而且揭示了Spring完成这些功能的原理,解释其功能和动机,以帮助读者使用该框架的所有部分来开发成功的应用程序。本书涵盖Spring的所有特性,并且演示了如何将其构成一个连贯的整体,帮助读者理解Spring方法的基本原理、何时使用Sping以及如何效仿最佳实践。所有......一起来看看 《Spring框架高级编程》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试