ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript学習メモ:配列(8)_html/css_WEB-ITnose

JavaScript学習メモ:配列(8)_html/css_WEB-ITnose

WBOY
WBOYオリジナル
2016-06-24 11:24:42851ブラウズ

多くの場合、値を取得するために配列項目を蓄積する必要があります (合計など)。同様の問題に遭遇した場合、どのような解決策を思いつきますか?あなたも私と同じように、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() メソッド

reduce() メソッドは関数 callbackfn をアキュムレーターとして受け取り、配列内の各値 (左から右) が 1 つの値にマージされます。

構文

array.reduce(callbackfn,[initialValue])

reduce() メソッドは callbackfn 関数を受け取り、この関数には 4 つのパラメータが含まれます:

function callbackfn(preValue,curValue,index,array){}
  • preValue : 最後のコールバック呼び出しによって返された値、または指定された初期値 (initialValue)
  • curValue : 配列内の現在処理されている配列項目
  • Index : 配列内の現在の配列項目のインデックス値
  • array :reduce() メソッドが呼び出される配列

そして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回実行し、各回のパラメータと戻り値は以下の通りです。

... 1,2, 3,4]15
最初のコールバック曲 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 番目のコールバック

这样一来,不用多说,应该都知道,可以使用 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

同时看看所费时间的对比:

循环类型 最终值(和) 所费时间
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()); // 21console.timeEnd("ruduceRight"); // 5.725ms

总结

reduce() 和 reduceRight() 两个方法功能都是类似的,可以让数组调用一个回调函数 callbackfn 作为累加器。实际上根据这个回调函数,可以实现不同的功能,比如说,对数组项求合;将多个数组合并到一个数组等等。甚至配合数组其他的方法你还可以做更多功能的处理。如果感兴趣的话不仿尝试一二。

初学者学习笔记,如有不对,还希望高手指点。如有造成误解,还希望多多谅解。

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。中国Drupal社区核心成员之一。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。