第一次见到reduce 是在js 的高级程序设计中,它的意思是把一个数组减少为一个数,举的例子是数组中元素的求和。它接受一个函数作为参数,函数又有两个参数,一个是prev, 前一个值,一个是next, 后一个值,然后函数体就是返回相加的值。

let array = [1, 3, 5];
let sum = array.reduce((prev, next) => {
return prev + next;
}) console.log(sum);
  我对reduce 的理解也仅限于此,只停留在了表面,当然,除了这个例子之后,我也不会用reduce. 今天在读js函数式编程相关书籍的时候,又遇到reduce, 仔细读了几遍,加深了理解,大体上懂了它的原理和用法。
  reduce 确实是把数组减少为一个值,也是接受一个函数作为参数,但它还有一个可选的第二个参数。对函数接受的两个参数的理解也有偏差,第一个参数准确来讲应该是个累计值,第二个参数应该是数组的每一个项的值。还是数组的求和为例,我们完全可以不用recude, 直接循环遍历数组就可以。那么我们该怎么做呢?
  先声明一个变量,来存储求和后的值。

let sum = 0;
  然后循环遍历数组的每一项,和sum 进行相加

for (let index = 0; index < array.length; index++) {
const element = array[index];
sum = sum + element;
}

  完全没有问题,可以求出数组中的元素的和。数组元素的求和应该都是这样的步骤,我们尝试把这个步骤封装一下, 先直接定义一个函数把所有步骤包含起来, 只把console.log(sum) 变成return sum;

function reduce () {

  let sum = 0;

  for (let index = 0; index < array.length; index++) {
const element = array[index];
sum = sum + element;
} return sum;
}

  现在来看封装的函数,可以发现有几个问题:

  1,let sum = 0 不太合适,在函数中固定一个变量的值,不具有灵活性。这个很简单,可以声明一个变量,让sum 等于传递进行的值。如果没有,可以默为0 , 变量为initValue;

  2,这个问题也很简单地,就是要遍历的数组,要把数组传递进来,所以要接受一个数组参数,用来进行遍历。
  3,这个问题可能不太好理解,但也是最关键的。第三个问题是在sum = sum + element;sum + element是这个函数要做的事情,如果不指定,这个reduce 函数只能做求和运算。我们想让这个函数更为通用,函数要做的事情就要让用户进行指定。要做的事情,在js 中,可以用函数进行表示,所以接受一个函数做为参数,这个函数要接受两个参数sum, elemnet, 然后在函数体中指定这个函数要做什么事情。由于sum + element 的值要赋值为sum, 所以这个函数还要有返回值。
function reduce (array, fn, initValue) {
let sum ; initValue ? (sum =initValue): (sum = 0); // 然后循环遍历数组的每一项,和sum 进行相加
for (let index = 0; index < array.length; index++) {
const element = array[index];
sum = fn(sum, element);
} return sum;
}

  调用我们自己封装的reduce 时行数组的求和

let result = reduce(array, (sum, element) => sum  + element);

  现在我们来对比原生的调用方式和自己封装的方式?可以发现没有本质不同。唯一的不同可能是我们的第一个参数是数组,而原生没有,这是因为原生的方法是定义在数组原型上,所 以没有接受数组作为参数,对于理解reduce 函数来说,这没有什么本质的不同。通过封装的过程,我们更能明白接受的函数的参数的意思。这个函数至少要接受两个参数,第一个参数的真正意义应该是调用函数所返回的值,由于在第一个调用函数之前,没有返回值,所以我们可以给它赋初值,或通过第三个参数,或直接调为0。 第二个参数,就是数组的每一项,只有不停的遍历数组中的每一项,最终才能把数组变成一个值。其实初值还有一个更好的办法,如果没有传递进来,可以取数组的第一项作为初始值。最终的函数可能如下:

const reduce = (array, fn, initialValue) => {
let sum;
if (initialValue) {
sum = initialValue;
for (const value of array) // 这里用了es6 在for of
sum = fn(sum, value)
}
else {
sum = array[0];
for (let i = 1; i < array.length; i++)
sum = fn(sum, array[i])
}
return sum;
}

  通过以上分析,我们可以看到,reduce函数真正的核心在于传递进去的函数。正确的使用reduce 就是要正确的写好这个函数,通常这个函数要满足一下,几点要求。

  1, 这个函数至少要接受两个参数进行计算,一个参数是累计值,一个参数是数组的每一个元素

  2, 这个函数必须要有返回值,因为要用它进行下一步的运算,并且,必须返回一个由参数进行计算的得到结果值,最后返回的值,还是要和数组中的元素类型相同,这还是因为它要进行下一步的运算。

  3, 初始的结果值,可以由第三个参数进行传递,也可以不传,如果不传的话,初始的累计值默认为第一个参数。

数组中的reduce 函数理解的更多相关文章

  1. JS中的reduce函数

    海纳百川,有容乃大 定义: reduce()方法接受一个函数作为累加器,数组中的每个值(从左向右)开始缩减,最终计算为一个值.对空数组是不会执行回调函数的. 案例: 计算数组总和: var num = ...

  2. python中filter(),reduce()函数

    filter()函数 是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 和一个list,这个函数的作用是对每个元素进行判断,返回 True或 False,filter() ...

  3. PHP:第四章——数组中的排序函数

    <pre> <?php header("Content-Type:text/html;charset=utf-8"); //1) /*sort - 对数组进行升序 ...

  4. 数组中的reduce

    reduce方法第一次对我的感觉是很鸡肋,但是深入了解,才发现其中的奥妙,是个非常强大且实用的方法 var arr = [1,2,3,4,5,6,7]; var sum = arr.reduce( ( ...

  5. python中的reduce函数

    python中的reduce   python中的reduce内建函数是一个二元操作函数,他用来将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给reduce中的函数 func()(必须是 ...

  6. 【C++函数题目】重载求数组中最小值的函数

    题目来源:https://acm.ujn.edu.cn Time Limit: 1 Sec  Memory Limit: 128 MB Description 写一个函数名称为miniElement( ...

  7. Pychram中使用reduce()函数报错:Unresolved reference 'reduce'

    python3不能直接使用reduce()函数,因为reduce() 函数已经被从全局名字空间里移除了,它现在被放置在fucntools 模块里,所以要使用reduce函数得先饮用fucntools ...

  8. functools 中的 reduce 函数基本写法

    reduce 返回的往往是一整个可迭代对象的 操作结果 reduce(函数,可迭代对象) 注:lambda x,y 两个参数 2020-05-04

  9. Python中的reduce()函数

    reduce()函数也是Python内置的一个高阶函数.reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收 ...

随机推荐

  1. 一致性Hash漫画图解

    一年之前—— 未来两年内,系统预估的总订单数量可达一亿条左右. 按Mysql单表存储500万条记录来算,暂时不必分库,单库30个分表是比较合适的水平分表方案. 于是小灰设计了这样的分表逻辑: 订单表创 ...

  2. 【我们一起写框架】MVVM的WPF框架(四)—DataGrid

    前言 这个框架写到这里,应该有很多同学发现,框架很多地方的细节,其实是违背了MVVM的设计逻辑的. 没错,它的确是违背了. 但为什么明知道违背设计逻辑,还要这样编写框架呢? 那是因为,我们编写的是框架 ...

  3. Python编程从入门到实践笔记——用户输入和while循环

    Python编程从入门到实践笔记——用户输入和while循环 #coding=utf-8 #函数input()让程序暂停运行,等待用户输入一些文本.得到用户的输入以后将其存储在一个变量中,方便后续使用 ...

  4. 【大数据安全】CDH集群禁用Kerberos

    在调试Kerberos的时候可能会有需要禁用的场景.以下是各组件禁用Kerberos的相关配置. 环境 CDH版本:5.11.2 Linux版本:7.4.1708 Docker版本:Docker ve ...

  5. [Vue] vue中setInterval的问题

    vue中使用setInterval this.chatTimer = setInterval(() => { console.log(this.chatTimer); this.chatMsg( ...

  6. Flutter 即学即用系列博客——03 在旧有项目引入 Flutter

    前言 其实如果打算在实际项目中引入 Flutter,完全将旧有项目改造成纯 Flutter 项目的可能性比较小,更多的是在旧有项目引入 Flutter. 因此本篇我们就说一说如何在旧有项目引入 Flu ...

  7. Servlet_note

    2015/8/24 Web项目目录结构:总目录my,中有WEB-INF目录,中有classes.lib两目录和web.xml文件.classes保存编译好的java文件,lib保存库文件,web.xm ...

  8. FeignClient注解及参数

    一.FeignClient注解 FeignClient注解被@Target(ElementType.TYPE)修饰,表示FeignClient注解的作用目标在接口上 1 2 3 4 5 @FeignC ...

  9. 配置多版本jdk

    配置办法https://blog.csdn.net/qq342643414/article/details/78364601 可能会遇到的问题https://www.cnblogs.com/chuij ...

  10. mysql索引结构及其原理

    1.定义 索引是一种数据结果,帮助提高获取数据的速度 为了提高查找速度,有很多查询优化算法.但是每种查找算法都只能应用于特定数据结构之上. 索引就是数据库创建的满足特定查找算法的数据结构,这些数据结构 ...