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:。


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

查看所有标签

猜你喜欢:

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

Perl语言编程

Perl语言编程

[美] Larry Wall、Tom Christiansen、Jon Orwant / 何伟平 / 中国电力出版社 / 2001-12 / 129.00元

这不仅仅是一本关于Perl的书籍,更是一本独一无二的开发者自己介绍该语言及其文化的书籍。Larry Wall是Perl的开发者,他就这种语言的未来发展方向提出了自己的看法。Tom Christiansen是最早的几个拥护者之一,也是少数几个在错综复杂的中游刃有余的人之一。Jon Orwant是《Perl Journal》的主编,该杂志把Perl社区组合成了一个共同的论坛,以进行Perl新的开发。一起来看看 《Perl语言编程》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具