重新学习Array.reduce()

最近在项目里抠语言包的过程中发现做了很多重复的工作,然后同事指点了一下reduce这个方法,仿佛打开了新世界的大门。遂重新学习了一下reduce的用法。在博客记录一下。

提示:努力想把文章写的精简,但是觉得关于这个函数很多细节想写。所以这篇观感可能会是: 博主是个bb怪。 

测试:

如果你能理解下列函数的原理,那么这篇文章你完全没有阅读必要。

// 版本1
[...new Array(100).values()].map((item, index) => index + 2).reduce((a, b) => `${a} MINE_${b}: "", \n`, 'MINE_1: "",');

// 另一种写法
[...new Array(100).toString().split(',').keys()].reduce((a, b) => `${a} MINE_${b}: "", \n`,'');

一、定义 

array.reduce( function(accumulator,  currentValue,  currentIndex,  array), initialValue ); 

accumulator:上一次调用回调返回的值,或者是提供的初始值(initialValue)

currentValue:数组中正在处理的元素

currentIndex:数据中正在处理的元素索引,如果提供了 initialValue ,从0开始;否则从1开始。【可选】

array: 调用 reduce 的数组【可选】

initialValue:可选项,其值用于第一次调用 callback 的第一个参数。如果没有设置初始值,则将数组中的第一个元素作为初始值。【可选】这里注意如果对一个空数组使用 [ ].reduce 方法会报错。原因看下面例子。

array.reduce 的返回值是这个函数累计处理的结果。

// 用代码解释定义
let demo = [ 333, 222, 111 ];

//没有定义initialValue
demo.reduce((acc, curVal) => { console.log(acc) })  
// 输出: 333, undefined, undefined 

//定义initialValue为1
demo.reduce((acc, curVal) => { console.log(acc)}, 1)
// 输出: 1, undefined, undefined 

//空数组不定义initialValue
[].reduce((a,b) => console.log(a))
// 输出:Uncaught TypeError: Reduce of empty array with no initial value
// 因为没有定义初始值,a会默认取数组第一个值,而空数组,第一个值是undefined,所以报错。

/* 说明:回调函数第一次执行时,accumulator 和currentValue的取值有两种情况:如果调用reduce()时提供了initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值;如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值。输出中有undefined 是因为acc返回的是上一次函数返回的结果,但这里我们函数仅是打印,没有返回值,所以是undefined */

二、它可以方便的做一些事

数组求和

将数组转化为对象、计算数组中每个元素出现的次数、按属性对数组分类

按顺序运行promise

2.1 数组求和

let demo = [ { x: 1}, { x: 2 }, { x: 3} ],

demo.reduce((arr,val) => { return arr + val.x }, 0); 

// return: 6

2.2 数组转化为对象

let demo = [
  {
    id: 1,
    username: 'john',
    sex: 1,
    email: 'john@163.com'
  },
  {
    id: 2,
    username: 'jerry',
    sex: 1,
    email: 'jerry@163.com'
  },
  {
    id: 3,
    username: 'nancy',
    sex: 0,
    email: ''
  }
];

demo.reduce( (acc,val) => { return {...acc, [val.username]: val} } , {} )

2.3 按顺序执行promise

/**
 * 直接抄官网的例子
 * Runs promises from array of functions that can return promises
 * in chained manner
 *
 * @param {array} arr - promise arr
 * @return {Object} promise object
 */
function runPromiseInSequence(arr, input) {
  return arr.reduce(
    (promiseChain, currentFunction) => promiseChain.then(currentFunction),
    Promise.resolve(input)
  );
}

// promise function 1
function p1(a) {
  return new Promise((resolve, reject) => {
    resolve(a * 5);
  });
}

// promise function 2
function p2(a) {
  return new Promise((resolve, reject) => {
    resolve(a * 2);
  });
}

// function 3  - will be wrapped in a resolved promise by .then()
function f3(a) {
 return a * 3;
}

// promise function 4
function p4(a) {
  return new Promise((resolve, reject) => {
    resolve(a * 4);
  });
}

const promiseArr = [p1, p2, f3, p4];
runPromiseInSequence(promiseArr, 10)
  .then(console.log);   // 1200

2.4 数组去重

reduce当然也能做到,但是我更喜欢下面这个方式

let demo = [ 1, 1, 2, 3];

//一行完成数组去重并升序排序
[...new Set(demo)].sort();

参考链接:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

https://www.jianshu.com/p/b415e46b4c8a

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值