在廖雪峰老师的JS教程关于map和reduce的一些笔记,大体是复制了廖老师的文章,在此基础上加了一些MDN文档内容、测试案例与理解补充。
如有错误欢迎指正与讨论。
参考链接
廖雪峰老师的JS教程
map
详细链接:MDN文档-map
map()
方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
参数
-
callback
生成新数组元素的函数,使用三个参数:
currentValue
callback
数组中正在处理的当前元素。**
index
**可选
callback
数组中正在处理的当前元素的索引。**
array
**可选
map
方法调用的数组。 -
thisArg
可选执行
callback
函数时值被用作this
。
返回值
一个由原数组每个元素执行回调函数的结果组成的新数组。
一定要return
返回内容!否则就会默认返回undefined
。
需要注意传入的函数的参数。
'use strict';
function pow(x) {
return x * x;
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var results = arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
注意:map()
传入的参数是pow
,即函数对象本身。
易错案例
通常情况下,map
方法中的 callback
函数只需要接受一个参数,就是正在被遍历的数组元素本身。但这并不意味着 map
只给 callback
传了一个参数。这个思维惯性可能会让我们犯一个很容易犯的错误。
考虑下例:
["1", "2", "3"].map(parseInt);
我们期望输出 [1, 2, 3]
, 而实际结果是 [1, NaN, NaN]
.
parseInt(string, radix);
radix
是字符串的基数,10不是默认值!
详细链接:MDN文档-parseInt
parseInt 经常被带着一个参数使用, 但是这里接受两个。第一个参数是一个表达式而第二个是callback function的基, Array.prototype.map
传递3个参数:
- the element
- the index
- the array
第三个参数被parseInt忽视了, but not the second one, 但不是第二个。因此可能出现混淆。下面是迭代步骤的简明示例:
// parseInt(string, radix) -> map(parseInt(value, index))
/* first iteration (index is 0): */ parseInt("1", 0); // 1
/* second iteration (index is 1): */ parseInt("2", 1); // NaN
/* third iteration (index is 2): */ parseInt("3", 2); // NaN
解决方案:
function returnInt(element) {
return parseInt(element, 10);
}
reduce
详细链接:MDN文档-reduce
Array的reduce()
把一个函数作用在这个Array
的[x1, x2, x3...]
上,这个函数必须接收两个参数,reduce()
把结果继续和序列的下一个元素做累积计算,其效果就是:
[x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
比方说对一个Array
求和,就可以用reduce
实现:
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x + y;
}); // 25
语法
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
reduce
为数组中的每一个元素依次执行callback
函数,不包括数组中被删除或从未被赋值的元素,接受四个参数。
accumulator 累计器
currentValue 当前值
currentIndex 当前索引
array 数组
参数
-
callback
执行数组中每个值 (如果没有提供
initialValue则第一个值除外
)的函数,包含四个参数:accumulator
累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或
initialValue
(见于下方)。currentValue
数组中正在处理的元素。
index
可选数组中正在处理的当前元素的索引。 如果提供了
initialValue
,则起始索引号为0,否则从索引1起始。**
array
**可选调用
reduce()
的数组 -
initialValue
可选作为第一次调用
callback
函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。
返回值
函数累计处理的结果
var arr = [1, 3, 5, 7, 9];
// 未使用initialValue
var t = arr.reduce(function (x,y,z,m) {
console.log('x =' + x); // 1 5 12 22
console.log('y =' + y); // 3 5 7 9
console.log('z =' + z); // 1 2 3 4
console.log(arr[z]); // 3 5 7 9
console.log(m); // [1, 3, 5, 7, 9]...[1, 3, 5, 7, 9]
return x+y+z;
}); // 35
console.log(t);
// 使用initialValue
var sum = [0, 1, 2, 3].reduce(function (accumulator, currentValue) {
return accumulator + currentValue;
}, 0);
// 和为 6