数组中的reduce 函数理解

第一次见到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, 初始的结果值,可以由第三个参数进行传递,也可以不传,如果不传的话,初始的累计值默认为第一个参数。

原文地址:https://www.cnblogs.com/SamWeb/p/10204551.html

时间: 2024-10-02 11:56:37

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

python进阶一(函数式编程)【2-3 python中的reduce函数】

2-3 python中的reduce函数 python中reduce()函数 reduce()函数也是Python内置的一个高阶函数.reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值. 例如,编写一个f函数,接收x和y,返回x和y的和: 1 def f(x, y): 2 return x + y 调用 reduce(f, [

数组中的filter函数,递归以及一些应用。

当我们用一个东西时候我们必须知道的是?why---where----how---when.一个东西我们为什么用?在哪用?怎么用?何时用?而不是被动的去接受一些东西.用在js里边我觉得也会试用.一直追求源生js,虽然也都背过好多东西,但是随着时间的流逝,工作的繁忙都忘了,有时甚至一点印象都没有,这让我开始思考我的学习方法了已经思维方式了.我们要记得不是简单的那个单词然后开始联想这个单词有什么用?一定是我要做什么事情?然后联想到谁可以做.带有目的性的学习. 现在有十个人(也就是数组)需要我们把属虎的

数组中的reduce

reduce方法第一次对我的感觉是很鸡肋,但是深入了解,才发现其中的奥妙,是个非常强大且实用的方法 var arr = [1,2,3,4,5,6,7]; var sum = arr.reduce( (res,now)=>{ //参数res表示返回的结果,now代表当前项,第一次遍历默认情况下res是数组中的第一项, return res + now; }); console.log( sum ); //28 以上就是一个很实用的例子,累加数据中的每一项, var arr = [1,2,3,4,5

python中filter(),reduce()函数

filter()函数 是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 和一个list,这个函数的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list. 例如:要从一个list [1,3,4,5,6,7,9,10]中删除偶数,保留奇数,编写一个判断奇数的函数: def is_odd(x): return x%2==1 a=list(filter(is_odd,[1,3,4,

js中的reduce()函数

1. 首先看下语法如下 2 . 写了个demo如下 var fa = [1,2,3,4] function red(a, b) { console.log(arguments); return a + b; } fa.reduce(red) 3. 打印的结构如下 4. 总结 就是遍历数组元素,从头开始,依次往下,第一个参数是上一次的返回值,第二个参数是下一个数组元素,首次的时候第一个和第二个参数分别是 array[0],  array[1] 原文地址:https://www.cnblogs.co

结构体数组中元素为函数

1 #include<stdio.h> 2 typedef struct A 3 { 4 int a; 5 char b; 6 } a; 7 8 int foo() 9 { 10 return 1; 11 } 12 13 char boo() 14 { 15 return 'b'; 16 } 17 int main(int args,char * arg[]) 18 { 19 int i; 20 a a1[]= 21 { 22 {foo(),boo()}, 23 {foo(),boo()},

使用ES6的reduce函数,根据key去重

最近很着迷于ES6的函数,让代码变得更优雅.ES6里的reduce函数,平时用的不是特别多,真正用起来发现还是挺好用的. 想要实现的效果为: 原数组: let rawArr = [{id:'123'},{id:'456'},{id:'789'},{id:'123'}]; 根据id去重后的结果为 let rawArr = [{id:'123'},{id:'456'},{id:'789'}]; reduce函数介绍 在说如何去重之前,先来介绍一下reduce函数: array.reduce(call

Python之reduce函数使用示例

#!/usr/bin/env python # -*- coding:utf8 -*- '''reduce:处理一个序列,然后把序列进行合并操作''' ###在python中没有reduce函数,所以需要导入它(去掉前面的注释符即可) #from functools import reduce def reduce_test(f,array,i = None): if i is None: tmp = array.pop(0) else: tmp = i for num in array: tm

JavaScript中的回调函数

在学习JavaScript的过程中遇到了很多,使用到回调函数的例子,出现了许多疑问,就由一个栗子开始吧: 在JavaScript中接触的第一个回调函数是在setInterval()和setTimeout()中出现的: 1 var num = 10; 2 3 var interValId = setInterval(function (){ 4 console.log(num); 5 num--; 6 if(num==0){ 7 clearInterval(interValId); 8 } 9 }