ホームページ > 記事 > ウェブフロントエンド > JavaScript学習メモ:配列(8)_html/css_WEB-ITnose
多くの場合、値を取得するために配列項目を蓄積する必要があります (合計など)。同様の問題に遭遇した場合、どのような解決策を思いつきますか?あなたも私と同じように、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()); // 21console.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()); // 21console.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) には、他に 2 つの配列メソッド、reduce() と ReduceRight() が用意されています。これらは、配列のすべての配列項目を反復処理して、最終値を返します。以下のコンテンツでは、主にこの 2 つの方法について学習します。
reduce() メソッドは関数 callbackfn をアキュムレーターとして受け取り、配列内の各値 (左から右) が 1 つの値にマージされます。
array.reduce(callbackfn,[initialValue])
reduce() メソッドは callbackfn 関数を受け取り、この関数には 4 つのパラメータが含まれます:
function callbackfn(preValue,curValue,index,array){}
そしてInitialValue は最初のコールバックとして使用されます。fn 関数の最初のパラメータです。
reduce() メソッドは、配列内の削除された要素や値が割り当てられていない要素を除き、配列内の各要素に対してコールバック関数 callbackfn を順番に実行します。初期値 (または最後の値の戻り値) の 4 つのパラメーターを受け取ります。 callback function)、現在の要素の値、現在のインデックス、reduce() が呼び出される配列。
コールバック関数が初めて実行されるとき、reduce() を呼び出すときに initialValue が指定された場合、preValue と curValue は値になります。最初の preValue は initialValue に等しく、curValue は最初の値に等しくなります。配列;initialValue が指定されていない場合、preValue は配列の最初の値と等しく、`curValue は配列の 2 番目の値と等しくなります。
例を見てみましょう:
var arr = [0,1,2,3,4];arr.reduce(function (preValue,curValue,index,array) { return preValue + curValue;}); // 10
例のコールバック関数は 4 回実行され、各回のパラメーターと戻り値は次のとおりです:
preValue | curValue | インデックス | 配列 | 戻り値 | |
---|---|---|---|---|---|
最初のコールバック | 0 | 1 | 1 | [0,1,2,3,4] | 1 |
2 番目のコールバック | 1 | 2 | 2 | [0,1,2,3,4] | 3 |
3 番目のコールバック | 3 | 3 | 3 | [0,1,2,3,4] | 6 |
4 番目のコールバック | 6 | 4 | 4 | [0,1,2,3,4] | 10 |
上記の例のreduce()メソッドはinitialValueを提供しませんイニシャルvalue, next 上の例では、初期値 5 を提供するように少し変更します。このとき、reduce()メソッドはコールバックを5回実行し、各回のパラメータと戻り値は以下の通りです。
最初のコールバック曲 | 5 | 0 | 0 | [0,1,2,3,4] | 5 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2番目のコールバック | 5 | 1 | 1 | [ 0,1,2 ,3,4] | 6 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3 番目のコールバック | 6 | 2 | 2 | [0,1,2,3,4] | 8 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 番目のコールバック | ... 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()); // 21console.timeEnd("ruduce"); // 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 回调将会被调用四次,每次调用的参数及返回值如下:
如果提供一个初始值 initialValue 为 5 : var arr = [0,1,2,3,4];arr.reduceRight(function (preValue,curValue,index,array) { return preValue + curValue;}, 5); // 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()); // 21console.timeEnd("ruduceRight"); // 5.725ms 总结reduce() 和 reduceRight() 两个方法功能都是类似的,可以让数组调用一个回调函数 callbackfn 作为累加器。实际上根据这个回调函数,可以实现不同的功能,比如说,对数组项求合;将多个数组合并到一个数组等等。甚至配合数组其他的方法你还可以做更多功能的处理。如果感兴趣的话不仿尝试一二。 初学者学习笔记,如有不对,还希望高手指点。如有造成误解,还希望多多谅解。
大漠常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。中国Drupal社区核心成员之一。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。 |