#### 7.9.5 reduce(), reduceRight()

The reduce() and reduceRight() methods combine the elements of an array, using the function you specify, to produce a single value. This is a common operation in functional programming and also goes by the names “inject” and “fold.” Examples help illustrate how it works:

var a = [1,2,3,4,5] var sum = a.reduce(function(x,y) { return x+y }, 0); // Sum of values var product = a.reduce(function(x,y) { return x*y }, 1); // Product of values var max = a.reduce(function(x,y) { return (x>y)?x:y; }); // Largest value

reduce() takes two arguments. The first is the function that performs the reduction operation. The task of this reduction function is to somehow combine or reduce two values into a single value, and to return that reduced value. In the examples above, the functions combine two values by adding them, multiplying them, and choosing the largest. The second (optional) argument is an initial value to pass to the function.

Functions used with reduce() are different than the functions used with forEach() and map(). The familiar value, index, and array values are passed as the second, third, and fourth arguments. The first argument is the accumulated result of the reduction so far. On the first call to the function, this first argument is the initial value you passed as the second argument to reduce(). On subsequent calls, it is the value returned by the previous invocation of the function. In the first example above, the reduction function is first called with arguments 0 and 1. It adds these and returns 1. It is then called again with arguments 1 and 2 and it returns 3. Next it computes 3+3=6, then 6+4=10, and finally 10+5=15. This final value, 15, becomes the return value of reduce().

7.9 ECMAScript 5 Array Methods | 155

You may have noticed that the third call to reduce() above has only a single argument: there is no initial value specified. When you invoke reduce() like this with no initial value, it uses the first element of the array as the initial value. This means that the first call to the reduction function will have the first and second array elements as its first and second arguments. In the sum and product examples above, we could have omitted the initial value argument.

Calling reduce() on an empty array with no initial value argument causes a TypeError. If you call it with only one value—either an array with one element and no initial value or an empty array and an initial value—it simply returns that one value without ever calling the reduction function.

reduceRight() works just like reduce(), except that it processes the array from highest index to lowest (right-to-left), rather than from lowest to highest. You might want to do this if the reduction operation has right-to-left precedence, for example:

var a = [2, 3, 4]

// Compute 2^(3^4). Exponentiation has right-to-left precedence

var big = a.reduceRight(function(accumulator,value) {

return Math.pow(value,accumulator);

});

Note that neither reduce() nor reduceRight() accepts an optional argument that specifies the thisvalue on which the reduction function is to be invoked. The optional initial value argument takes its place. See the Function.bind() method if you need your reduction function invoked as a method of a particular object.

It is worth noting that the every() and some() methods described above perform a kind of array reduction operation. They differ from reduce(), however, in that they terminate early when possible, and do not always visit every array element.

The examples shown so far have been numeric for simplicity, but reduce() and reduce Right() are not intended solely for mathematical computations. Consider the union()function from Example 6-2 . It computes the “union” of two objects and returns a new object that has the properties of both. This function expects two objects and returns another object, so it works as a reduction function, and we can use reduce() to generalize it and compute the union of any number of objects:

var objects = [{x:1}, {y:2}, {z:3}]; var merged = objects.reduce(union); // => {x:1, y:2, z:3}

Recall that when two objects have properties with the same name, the union()function uses the value of that property from the first argument. Thus reduce() and reduce Right() may give different results when used with union():

var objects = [{x:1,a:1}, {y:2,a:2}, {z:3,a:3}]; var leftunion = objects.reduce(union); // {x:1, y:2, z:3, a:1} var rightunion = objects.reduceRight(union); // {x:1, y:2, z:3, a:3}

欢迎转载,转载请注明来自一手册:http://yishouce.com/book/1/31360.html