reduce() 方法按顺序在数组的每个元素上执行用户提供的“reducer”回调函数,并传入对前一个元素进行计算的返回值。 在数组的所有元素上运行 reducer 的最终结果是单个值。
使用 reduce 方法分析数据
reduce()(即Array.prototype.reduce()
),是 JavaScript 所有数组操作中最常用的方法。
几乎可以用 reduce 方法解决所有数组处理问题。
reduce 方法是处理数组更通用的方式,而且 filter 和 map 方法都可以当作是 reduce 的特殊实现。
reduce 方法遍历数组中的每个项目并返回单个值(即字符串、数字、对象、数组)。 这是通过在每次迭代中调用一个回调函数来实现的。
回调函数接受四个参数。
除了回调函数,reduce 还有一个额外的参数做为叠加器的初始值。
如果没有第二个参数,会跳过第一次迭代,第二次迭代给叠加器传入数组的第一个元素。
示例1:
给 users 数组使用 reduce 方法,返回所有用户数组的和。 为了简化,例子仅使用了回调函数的第一个参数和第二个参数。
1
2
3
4
5
6
7
8
9
|
const users = [
{ name: 'John', age: 34 },
{ name: 'Amy', age: 20 },
{ name: 'camperCat', age: 10 }
];
const sumOfAges = users.reduce((sum, user) => sum + user.age, 0);
console.log(sumOfAges); // 64
|
示例2:
返回一个包含用户名称做为属性,其年龄做为值的对象。
1
2
3
4
5
6
7
8
9
10
11
12
|
const users = [
{ name: 'John', age: 34 },
{ name: 'Amy', age: 20 },
{ name: 'camperCat', age: 10 }
];
const usersObj = users.reduce((obj, user) => {
obj[user.name] = user.age;
return obj;
}, {});
console.log(usersObj); // { John: 34, Amy: 20, camperCat: 10 }
|
更复杂的例子:
watchList 是包含一些电影信息的对象。
使用 reduce 查找由 Christopher Nolan 导演的电影的 IMDB 评级平均值。
回想一下之前的例子,如何 filter 数据,以及使用 map 来获取你想要的数据。
可能需要创建其他变量,并从 getRating 函数返回平均评分。
请注意,评级在对象中是字符串,需要将其转换为数字再用于数学运算。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
// 全局变量
const watchList = [
{
"Title": "Inception",
"Year": "2010",
"Director": "Christopher Nolan",
"imdbRating": "8.8"
},
{
"Title": "Interstellar",
"Year": "2014",
"Director": "Christopher Nolan",
"imdbRating": "9.0"
}
];
function getRating(watchList) {
let averageRating = watchList
// 使用过滤器查找克里斯托弗·诺兰 (Christopher Nolan) 导演的电影
.filter(film => film.Director === "Christopher Nolan")
// 使用 map 将他们的评分从字符串转换为数字
.map(film => Number(film.imdbRating))
// 使用 reduce 将他们的评分加在一起
.reduce((sumOfRatings, rating) => sumOfRatings + rating) /
// 除以诺兰片数得到平均评分
watchList.filter(film => film.Director === "Christopher Nolan").length;
return averageRating;
}
console.log(getRating(watchList)); // 8.9
|
使用高阶函数 map、filter 或者 reduce 来解决复杂问题
已经接触了高阶函数如 map()、 filter() 和 reduce()的使用,是时候用它们来完成一些复杂的挑战了。
使用 map()、filter() 和 reduce() 的任何组合完成 squareList 函数的代码。
传递一个包含实数的数组给函数时,函数应返回一个新的数组,只包含正整数(小数不是整数)的平方值, 例如 [-3, 4.8, 5, 3, -3.2] 这样一个包含实数的数组。
注意: 函数不应该包含任何形式的 for 或者 while 循环或者 forEach() 函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
const squareList = arr => {
// return arr
// .filter(num => num > 0 && num % parseInt(num) === 0)
// .map(num => Math.pow(num, 2));
// 或者
return arr.reduce((sqrIntegers, num) => {
return Number.isInteger(num) && num > 0
? sqrIntegers.concat(num * num)
: sqrIntegers;
}, []);
};
const squaredIntegers = squareList([-3, 4.8, 5, 3, -3.2]);
console.log(squaredIntegers); // [ 25, 9 ]
|