es6中reduce的用法_ES6中的数组reduce()方法详解

ES6的reduce方法用于将数组元素通过回调函数累计成单一值。它接受一个回调函数,可选的初始值。回调函数有四个参数:accumulator(累计器),currentValue(当前值),currentIndex(当前索引)和array(原数组)。若无初始值,reduce从索引1开始,否则从0开始。示例中展示了无初始值和提供初始值的reduce用法,以及求和、累加对象值、二维转一维和按属性分类等应用场景。当数组为空且无初始值时,reduce会抛出TypeError。
摘要由CSDN通过智能技术生成

目录

reduce() 方法对数组中的每个元素执行一个由我们提供的reducer函数(升序执行),将其结果汇总为单个返回值。

1. 语法reduce说明

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

第一个参数: callback函数

执行数组中每个值 (如果没有提供 initialValue则第一个值除外)的函数,包含四个参数:

accumulator

累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(见于下方)。

currentValue

数组中正在处理的元素。

index 可选

数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则从索引1起始。

array可选

调用reduce()的原数组

第二个参数: initialValue可选

作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。

这个看下来都有点蒙,其实就是两种情况,一种情况是给了初始值,一种是没提供也就是reduce的第二个参数initialValue。

reduce为数组中的每一个元素依次执行callback函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:

accumulator 累计器

currentValue 当前值

currentIndex 当前索引

array 数组

回调函数第一次执行时,accumulator 和currentValue的取值有两种情况:如果调用reduce()时提供了initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值;如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值。

如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供initialValue,从索引0开始。

为了理解透举个栗子:

展示:

1.  无初始值

假如运行下段reduce()代码:

[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){

return accumulator + currentValue;

});

callback 被调用四次,每次调用的参数和返回值如下表:

callback

accumulator

currentValue

currentIndex

array

return valuefirst call

0

1

1

[0, 1, 2, 3, 4]

1

second call

1

2

2

[0, 1, 2, 3, 4]

3

third call

3

3

3

[0, 1, 2, 3, 4]

6

fourth call

6

4

4

[0, 1, 2, 3, 4]

10

由reduce返回的值将是最后一次回调返回值(10)。

2.  添加初始值,这样子

提供一个初始值作为reduce()方法的第二个参数,以下是运行过程及结果:

[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => { return accumulator + currentValue; }, 10 );

// 提供初始值为 10

callback

accumulator

currentValue

currentIndex

array

return valuefirst call

10

0

0

[0, 1, 2, 3, 4]

10

second call

10

1

1

[0, 1, 2, 3, 4]

11

third call

11

2

2

[0, 1, 2, 3, 4]

13

fourth call

13

3

3

[0, 1, 2, 3, 4]

16

fifth call

16

4

4

[0, 1, 2, 3, 4]

20

这种情况下reduce()返回的值是20。

这个之后就理解透了。

2. 一些用途

求和

var total = [ 0, 1, 2, 3 ].reduce(

( acc, cur ) => acc + cur,

0

);

// total 6

累加对象里的值

let sum = [{x: 1}, {x:2}, {x:3}].reduce(

(accumulator, currentValue) => accumulator + currentValue.x

,0

);

console.log(sum) // logs 6

二维数组变一维

var flattened = [[0, 1], [2, 3], [4, 5]].reduce(

( acc, cur ) => acc.concat(cur),

[]

);

// [0, 1, 2, 3, 4, 5]

计算数组中每个元素出现的次数

const names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];

let countedNames = names.reduce(function (allNames, name) {

if (name in allNames) {

allNames[name]++;

}

else {

allNames[name] = 1;

}

return allNames;

}, {});

// countedNames is:

// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }

按属性对object分类

var people = [

{ name: 'Alice', age: 21 },

{ name: 'Max', age: 20 },

{ name: 'Jane', age: 20 }

];

function groupBy(objectArray, property) {

return objectArray.reduce(function (acc, obj) {

var key = obj[property];

if (!acc[key]) {

acc[key] = [];

}

acc[key].push(obj);

return acc;

}, {});

}

var groupedPeople = groupBy(people, 'age');

// groupedPeople is:

// {

// 20: [

// { name: 'Max', age: 20 },

// { name: 'Jane', age: 20 }

// ],

// 21: [{ name: 'Alice', age: 21 }]

// }

3. 极力避免的情况

未设置初始化值时

var maxCallback = ( acc, cur ) => Math.max( acc.x, cur.x );

var maxCallback2 = ( max, cur ) => Math.max( max, cur );

// reduce() 没有初始值

console.log([ { x: 2 }, { x: 22 }, { x: 42 } ].reduce( maxCallback ));

// NaN

// 返回NaN的原因是在第二次的时候返回值是22 而22再 22.x就不行了。

console.log([ { x: 2 }, { x: 22 } ].reduce( maxCallback ));

// 22 原因是只执行一次 这也是幸运了

console.log([ { x: 2 } ].reduce( maxCallback )); // { x: 2 }

console.log([ ].reduce( maxCallback ));

// TypeError

// 如果数组为空且没有提供initialValue,会抛出TypeError

// map/reduce; 这是更好的方案,即使传入空数组或更大数组也可正常执行

[ { x: 22 }, { x: 42 } ].map( el => el.x )

.reduce( maxCallback2, -Infinity );

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值