您的位置:首页 > Web前端 > JavaScript

JavaScript 之 reduce

2017-04-01 21:57 183 查看

引言

reduce 是 Array.prototype 中的一个方法,这个方法的作用是提供一个函数式的累加器,将数组中的每一个值进行累加最终减少到只有一个值。

先说说兼容性:

Chrome all、Firefor 3.0、IE 9 以上、Opera 10.5和 safari 4.0以上的版本均支持Array.prototype.reduce。


先看一个栗子:

const sum = [1, 2, 3, 4, 5].reduce( (acc, item) => acc + item, 0);
// sum = 6;

var list1 = [[0, 1], [2, 3], [4, 5]];
var list2 = [0, [1, [2, [3, [4, [5]]]]]];

const flatten = arr => arr.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);
flatten(list1); // returns [0, 1, 2, 3, 4, 5]
flatten(list2); // returns [0, 1, 2, 3, 4, 5]


用法:

arr.reduce( callback [, initialValue] )


参数:

reduce()方法接收两个参数,一个是callback(回调),另一个是可有可无的initialValue。

callback:
回调函数可以接收4个参数,分别是 accumulator、currentValue、currentIndex 和 array;

accumulator:
返回上一次 callback 运行返回的结果,或者是 initialVaule;

currentValue:
数组中,当前正在被处理的元素;

currentIndex:
数组中,当前正在被处理的元素的索引,起初为0,如果 initialValue 存在,则该参数初值为1;

array:
返回调用 reduce() 方法的数组;

initialValue:
可选的值,作为第一次调用 callback 的初始值,赋值于 accumulator;


返回值

调用 reduce() 方法返回的值,即最后一次 callback 执行完的 accumulator 的值。

处理过程描述

第一次 callback 被调用,
accumulator
currentValue
的值有两种情况:

如果
initialValue
被传入
reduce()
方法,
accumulator
等于
initialValue
的值,
currentValue
等于数组的第一个元素,同时
currentIndex
等于
0
;

如果
initialValue
没有传入
reduce()
方法,
accumulator
等于数组第一个元素的值,
currentValue
等于数组的第二个元素,同时
currentIndex
等于
1
;

请注意:

如果调用 `reduce()` 的数组为空并且没有传入 `initialValue`, `TyepError`错误会被抛出。

若该数组只有一个元素(即:lenght 为 1),并且 `initialValue` 还是没有传入 `reduce()` 方法
或者
若数组为空,但是传了 `initialValue`
`reduce()` 方法仅仅会返回单独(可能是`initialValue` 或者 数组唯一的元素`)的值,但是请注意,这个方法并没有执行 `callback` 的方法。


官方建议,
initialValue
的值最好不要舍去,否则可能会产生三种不同的结果。

一大堆栗子

求数组中每个元素累加的和:

var sum = [0, 1, 2, 3].reduce(function(a, b) {
return a + b;
}, 0);
// sum = 6

// ES6 箭头函数的写法:
var total = [ 0, 1, 2, 3 ].reduce( ( acc, cur ) => acc + cur, 0 );


将多重数组转换为一维数组:

var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
return a.concat(b);
}, []);
// flattened = [0, 1, 2, 3, 4, 5]

// ES6 箭头函数的写法:
var flattened = [[0, 1], [2, 3], [4, 5]].reduce( ( acc, cur ) => acc.concat(cur), [] );


统计数组中每个元素出现的次数,并转换为对象:

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

var countedNames = names.reduce( (acc, cur) => {
if (acc.hasOwnProperty(cur)) {
acc[cur]++;
} else {
acc[cur] = 1;
}

return acc;

}, {});

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


使用扩展运算符和
initialValue
,合并/数组中/每个对象/的/数组(比较绕,不好理解):

var friends = [
{ name: 'Anna', books: ['Bible', 'Harry Potter'], age: 21 },
{ name: 'Bob', books: ['War and peace', 'Romeo and Juliet'], age: 26 },
{ name: 'Alice', books: ['The Lord of the Rings', 'The Shining'], age: 18 }
];

var allbooks = friends.reduce(function(prev, curr) {
return [...prev, ...curr.books];
}, ['Alphabet']);

// allbooks = ['Alphabet', 'Bible', 'Harry Potter', 'War and peace', 'Romeo and Juliet', 'The Lord of the Rings', 'The Shining']
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript