0

Can someone help me understand what is going on in this code?

 function reduce(fn, a, init){
 var s = init;
 for (i = 0; i < a.length; i++)
 s = fn( s, a[i] );
 return s;
}
function sum(a)
{
 return reduce( function(a, b){ return a + b; }, 
 a, 0 );
}
function join(a)
{
 return reduce( function(a, b){ return a + b; }, 
 a, "" );
}

I guess the part that is throwing me of is the b variable and how it is used. Thanks for the help!

asked Apr 25, 2011 at 3:27
1
  • 1
    You should probably add a var before the i = 0 in the for loop; otherwise, reduce won't work recursively. Commented Apr 25, 2011 at 3:49

6 Answers 6

2

The reduce function takes some operator, •, which is implemented by fn, and computes the result of applying • to all the elements in turn:

reduce(•, [a, b, c, d, e], init) = init • a • b • c • d • e

In the case of sum, the operator implemented by fn is +, so you end up with init + a + b + c + d + e. Likewise for join (except that, over strings, + concatenates).

answered Apr 25, 2011 at 3:36
Sign up to request clarification or add additional context in comments.

Comments

0

the function reduce() is an aggregator function, executing the passed function fn on every element of the passed array a and passing a state (which initially has the value of init) along with it, representing the result of the previous call.

In the case of sum() i.e. it's summing up all elements of the array by passing the sum of all previous elements (s) to the next function call so the "aggregate" is the sum of all elements.

answered Apr 25, 2011 at 3:32

Comments

0

It is calling the function on every element in the array, passing the init (which is being updated on each iteration) and current array member.

It then returns the s value, which is the return from the values being passed through the function passed.

The sum() works because init is 0 (Number), so they are treated as Numbers.

The join() works because it passes an empty String (""), so they are treated as Strings.

answered Apr 25, 2011 at 3:29

Comments

0

b is a parameter to the anonymous function (fn) being passed to reduce. That function simply combines two values and returns the result. The reduce function calls fn repeatedly to combine the array into a single value. Note that the a parameter to reduce is not the same as the a parameter to the anonymous function.

EDIT: The example you requested:

var myArray = [1, 2, 3, 4, 5];
var mySum = sum(myArray);

Note that sum uses reduce.

answered Apr 25, 2011 at 3:33

2 Comments

how would I go about calling this reduce method on an array if it is already declared and what not so it adds up all of the elements and show result?
@Spence, I posted an example.
0

@Marcelo's answer is probably the best and most general explanation for this piece of code - that's the one you're looking for.


A. When invoked via sum, the function reduce gets 3 parameters

  • fn the function that sums two numbers
  • a, an array of numbers to be summed
  • b, the initial sum (set to 0)

    function reduce(fn, a, init){
    
    1. s is initialized to the intial sum value

      var s = init;
      
    2. For each element in a:

      for (i = 0; i < a.length; i++)
      
    3. The sum is calculated by invoking fn to add the last sum calculated, s, and the current element of the array a[i]

      s = fn( s, a[i] );
      
    4. And this sum is returned once all array elements have been added to s

      return s;
      }
      

B. When invoked via join, the function reduce gets 3 parameters

  • fn the function that concatenates two strings
  • a, an array of values to be concatenated
  • b, the initial string (the empty string "")

It does pretty much the same as explained above except it returns a string which is the concatenation of all values in the array.

answered Apr 25, 2011 at 3:36

Comments

0
// All new browsers implement a native reduce method for arrays-
// it might be better to shim older browsers to use the same method,
// so that you can use the native method where available.
if(!Array.prototype.reduce){
 Array.prototype.reduce= function(fun, temp, scope){
 var i= 0, T= this, len= T.length, temp;
 if(scope== undefined) scope= window;
 if(typeof fun=== 'function'){
 if(temp== undefined) temp= T[i++];
 while(i < len){
 if(i in T) temp= fun.call(scope, temp, T[i], i, T);
 i++;
 }
 }
 return temp;
 }
 Array.prototype.reduceRight= function(fun, temp, scope){
 var T= this.concat().reverse();
 return T.reduce(fun, temp, scope);
 }
}
var A=[1,2,3,4,5,6,7,8,9,10];
/* A.reduce(function(a,b){return a+b});
value: (Number)55
A.reduce(function(a,b){return a*b});
 value: (Number)3628800
*/
answered Apr 25, 2011 at 4:34

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.