JavaScript学习笔记:数组reduce()和reduceRight()方法
很多时候需要累加数组项的得到一个值(比如说求和)。如果你碰到一个类似的问题,你想到的方法是什么呢?会不会和我一样,想到的就是使用for或while循环,对数组进行迭代,依次将他们的值加起来。比如:
var arr = [1,2,3,4,5,6];
Array.prototype.sum = function (){
var sumResult = 0;
for (var i = 0; i < this.length; i++) {
sumResult += parseInt(this[i]);
}
return sumResult;
}
arr.sum(); // 21
或者
var arr = [1,2,3,4,5,6];
Array.prototype.sum = function () {
var sumResult = 0;
var i = this.length;
while (i--) {
sumResult += parseInt(this[i]);
}
return sumResult;
}
arr.sum(); // 21
那他们是不是最好的方案呢?先来看看他们所耗时间。
// 测试for和while循环实现数组求和的性能
var arr = [1,2,3,4,5,6];
// for循环
console.time("forLoop");
Array.prototype.forLoop = function (){
for (var i = 0; i < 10000; i++) {
var sumResult = 0;
for (var j = 0; j < this.length; j++) {
sumResult += parseInt(this[j]);
}
}
return sumResult;
}
arr.forLoop();
console.log('最终的值:' + arr.forLoop()); // 21
console.timeEnd("forLoop"); // 54.965ms
再来看看while循环所用时间:
var arry = [1,2,3,4,5,6];
console.time("whileLoop");
Array.prototype.whileLoop = function () {
for (var i = 0; i < 10000; i++) {
var sumResult = 0;
for (var j = 0; j < this.length; j++) {
sumResult += parseInt(this[j]);
}
}
return sumResult;
}
arry.whileLoop();
console.log('最终的值:' + arry.whileLoop()); // 21
console.timeEnd("whileLoop"); // 53.056ms
看看对比结果
| 循环类型 | 最终值(和) | 所费时间 |
|---|---|---|
| for | 21 | 54.965ms |
| while | 21 | 53.056ms |
备注:数组[1,2,3,4,5,6]做了10000次循环的累加。
虽然上面使用for和while都能实现需要的效果,但在JavaScript中有没有更好的方案呢?回答是肯定的,在JavaScript中(ESMAScript 5)提供了另外两个数组的方法reduce()和reduceRight(),这两个数组会迭代数组的所有数组项,然后返回一个最终值。接下来的内容,主要来学习这两种方法。
reduce()方法
reduce()方法接收一个函数callbackfn作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值。
语法
array.reduce(callbackfn,[initialValue])
reduce()方法接收callbackfn函数,而这个函数包含四个参数:
function callbackfn(preValue,curValue,index,array){}
preValue: 上一次调用回调返回的值,或者是提供的初始值(initialValue)curValue: 数组中当前被处理的数组项index: 当前数组项在数组中的索引值array: 调用reduce()方法的数组
而initialValue作为第一次调用 callbackfn函数的第一个参数。
reduce()方法为数组中的每一个元素依次执行回调函数callbackfn,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce() 的数组。
回调函数第一次执行时,preValue 和 curValue 可以是一个值,如果 initialValue 在调用 reduce() 时被提供,那么第一个 preValue 等于 initialValue ,并且curValue 等于数组中的第一个值;如果initialValue 未被提供,那么preValue 等于数组中的第一个值,`curValue等于数组中的第二个值。
来看一个示例:
var arr = [0,1,2,3,4];
arr.reduce(function (preValue,curValue,index,array) {
return preValue + curValue;
}); // 10
示例中的回调函数被执行四次,每次参数和返回的值如下:
| preValue | curValue | index | array | 返回值 | |
|---|---|---|---|---|---|
| 第一次回调 | 0 | 1 | 1 | [0,1,2,3,4] | 1 |
| 第二次回调 | 1 | 2 | 2 | [0,1,2,3,4] | 3 |
| 第三次回调 | 3 | 3 | 3 | [0,1,2,3,4] | 6 |
| 第四次回调 | 6 | 4 | 4 | [0,1,2,3,4] | 10 |
上面的示例reduce()方法没有提供initialValue初始值,接下来再上面的示例中,稍作修改,提供一个初始值,这个值为5。这个时候reduce()方法会执行五次回调,每次参数和返回的值如下:
var arr = [0,1,2,3,4];
arr.reduce(function (preValue,curValue,index,array) {
return preValue + curValue;
}, 5); //15
| preValue | curValue | index | array | 返回值 | |
|---|---|---|---|---|---|
| 第一次回调 | 5 | 0 | 0 | [0,1,2,3,4] | 5 |
| 第二次回调 | 5 | 1 | 1 | [0,1,2,3,4] | 6 |
| 第三次回调 | 6 | 2 | 2 | [0,1,2,3,4] | 8 |
| 第四次回调 | 8 | 3 | 3 | [0,1,2,3,4] | 11 |
| 第五次回调 | 11 | 4 | 4 | [0,1,2,3,4] | 15 |
这样一来,不用多说,应该都知道,可以使用reduce()实现数组求和的功能。如:
var arr = [1,2,3,4,5,6];
Array.prototype.sum = function (){
var sumResult = 0;
return this.reduce(function (preValue, curValue) {
return sumResult = preValue + curValue;
});
return sumResult;
}
arr.sum(); // 21
回到文章的前面,来看看使用reduce()方法对数组求和,需要多少时间:
var arr = [1,2,3,4,5,6];
console.time("ruduce");
Array.prototype.ruduceSum = function (){
for (var i = 0; i < 10000; i++) {
return this.reduce (function (preValue, curValue) {
return preValue + curValue;
});
}
}
arr.ruduceSum();
console.log('最终的值:' + arr.ruduceSum()); // 21
console.timeEnd("ruduce"); // 0.417ms
同时看看所费时间的对比:
| 循环类型 | 最终值(和) | 所费时间 |
|---|---|---|
| for | 21 | 54.965ms |
| while | 21 | 53.056ms |
| reduce | 21 | 0.417ms |
在Chrome浏览器下,每次执行的数据都会略有不同,但可以明显的看出reduce()对数组项求和所费时间是最短的。
reduceRight()方法
reduceRight()方法的功能和reduce()功能是一样的,不同的是reduceRight()从数组的末尾向前将数组中的数组项做累加。
reduceRight()首次调用回调函数callbackfn时,prevValue 和 curValue 可以是两个值之一。如果调用 reduceRight() 时提供了 initialValue 参数,则 prevValue 等于 initialValue,curValue 等于数组中的最后一个值。如果没有提供 initialValue 参数,则 prevValue 等于数组最后一个值, curValue 等于数组中倒数第二个值。
来看实例:
var arr = [0,1,2,3,4];
arr.reduceRight(function (preValue,curValue,index,array) {
return preValue + curValue;
}); // 10
回调将会被调用四次,每次调用的参数及返回值如下:
| preValue | curValue | index | array | 返回值 | |
|---|---|---|---|---|---|
| 第一次回调 | 4 | 3 | 3 | [0,1,2,3,4] | 7 |
| 第二次回调 | 7 | 2 | 2 | [0,1,2,3,4] | 9 |
| 第三次回调 | 9 | 1 | 1 | [0,1,2,3,4] | 10 |
| 第四次回调 | 10 | 0 | 0 | [0,1,2,3,4] | 10 |
如果提供一个初始值initialValue为5:
var arr = [0,1,2,3,4];
arr.reduceRight(function (preValue,curValue,index,array) {
return preValue + curValue;
}, 5); // 15
回调将会被调用五次,每次调用的参数及返回的值如下:
| preValue | curValue | index | array | 返回值 | |
|---|---|---|---|---|---|
| 第一次回调 | 5 | 4 | 4 | [0,1,2,3,4] | 9 |
| 第二次回调 | 9 | 3 | 3 | [0,1,2,3,4] | 12 |
| 第三次回调 | 12 | 2 | 2 | [0,1,2,3,4] | 14 |
| 第四次回调 | 14 | 1 | 1 | [0,1,2,3,4] | 15 |
| 第五次回调 | 15 | 0 | 0 | [0,1,2,3,4] | 15 |
同样的,可以对一个数组求和,也可以使用reduceRight()方法:
var arr = [1,2,3,4,5,6];
console.time("ruduceRight");
Array.prototype.ruduceRightSum = function (){
for (var i = 0; i < 10000; i++) {
return this.reduceRight (function (preValue, curValue) {
return preValue + curValue;
});
}
}
arr.ruduceRightSum();
console.log('最终的值:' + arr.ruduceSum()); // 21
console.timeEnd("ruduceRight"); // 5.725ms
总结
reduce()和reduceRight()两个方法功能都是类似的,可以让数组调用一个回调函数callbackfn作为累加器。实际上根据这个回调函数,可以实现不同的功能,比如说,对数组项求合;将多个数组合并到一个数组等等。甚至配合数组其他的方法你还可以做更多功能的处理。如果感兴趣的话不仿尝试一二。
初学者学习笔记,如有不对,还希望高手指点。如有造成误解,还希望多多谅解。
大漠
如需转载,烦请注明出处:http://www.w3cplus.com/javascript/array-part-8.html
JavaScript学习笔记:数组reduce()和reduceRight()方法的更多相关文章
- Java程序猿的JavaScript学习笔记(9—— jQuery工具方法)
计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...
- JavaScript学习笔记-数组(1)
数组是值的有序集合.每个值叫做一个元素,而每个元素在数组中有一个位置,以数字表示,称为索引.JavaScript数组是无类型的:数组元素可以是任意类型,并且同一个数组中的不同元素也可能有不同的类型.数 ...
- JavaScript学习笔记-数组
数组 数组中的每个元素的位置是索引,索引是基于32位的由0开始的数值,最大索引为(2的32次方-2),最大长度为(2的32次方-3) 数组是无类型的:元素可为任意类型:动态的:可根据需要自动增长.缩减 ...
- JavaScript学习笔记-用于模式匹配的String方法
用于模式匹配的String方法: String支持4种使用正则表达式的方法: seach()用于检索,参数是一个正则表达式,返回第一个与之匹配的子串的位置,找不到则返回-1,如 ...
- JavaScript学习笔记- 正则表达式常用字符集及方法
正则表达式修饰符(修饰符 可以在全局搜索中不区分大小写) i(ignoreCase)执行对大小写不敏感的匹配 g (global) 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止) m( ...
- JavaScript学习笔记——数组
javascript数组数组是一个可以存储 一组 或是 一系列 相关数据 的 容器. 一.为什么要使用数组. (1)为了解决大量相关数据的存储和使用的问题. (2)模拟真是的世界. 二.如何创建数组 ...
- JavaScript学习笔记(1)字符串方法
字符串方法 length 属性返回字符串的长度 var txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var sln = txt.length; inde ...
- Java程序猿的JavaScript学习笔记(5——prototype和Object内置方法)
计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...
- Java程序猿的JavaScript学习笔记(8——jQuery选择器)
计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...
随机推荐
- windows平台使用Microsoft Visual C++ Compiler for Python 2.7编译python扩展
在windows平台上安装python c extension的扩展包是件很痛苦的事情,一般通过安装vc/vs系列来编译C扩展,不过安装包都比较大.或者通过mingw编译,不过有时会在兼容性上出现点问 ...
- MySQL调试
http://dev.mysql.com/doc/refman/5.5/en/signal.html#signal-condition-information-items http://www.dev ...
- arcgis api for silverlight
原文 http://blog.sina.com.cn/s/blog_4638cf7b0100wntt.html arcgis api for silverlight(1) (2011-09-21 09 ...
- 关于 MVC 字段 默认值
以下是网友的疑问: ================================================================ Html.EditorFor(model=> ...
- android面试题集1
Android 面试题(有详细答案) 附带答案,共100分 一.选择题(30题,每题1.5分,共45分) 1.java.io包中定义了多个流类型来实现输入和输出功能,可以从不同的角度对其进行分类,按功 ...
- Co-prime Array&&Seating On Bus(两道水题)
Co-prime Array Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Su ...
- LED音乐频谱之输出数据处理
转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/38023539 一.PWM调节 1.初始化 void DACInit() { C ...
- poj 2446 (二分匹配)
题意:除了所给的一些点外,问能不能用1*2的矩形覆盖所有的点,矩形间不能重叠. 思路:简单二分匹配,,,,,,, #include<stdio.h> #include<string. ...
- C/C++中经常使用的字符串处理函数和内存字符串函数
一. 字符处理函数 1. 字符处理函数:<ctype.h> int isdigit(int ch) ;//是否为数字,即ch是否是0-9中的字符 int ...
- poj 2429 Pollard_rho大数分解
先对lcm/gcd进行分解,问题转变为从因子中选出一些数相乘,剩下的数也相乘,要求和最小. 这里能够直接搜索,注意一个问题,因为同样因子不能分配给两边(会改变gcd)所以能够将同样因子合并,这种话,搜 ...