JS Array.prototype.reduce的一些理解

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

内容简介: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:。


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

查看所有标签

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

DOM Scripting

DOM Scripting

Jeremy Keith / friendsofED / 2010-12 / GBP 27.50

There are three main technologies married together to create usable, standards-compliant web designs: XHTML for data structure, Cascading Style Sheets for styling your data, and JavaScript for adding ......一起来看看 《DOM Scripting》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具