digiscripter
digiscripter

Reputation: 309

curly braces around for-loop alters output

Working on Eloquent Javascript chapter on high order functions, I came accross this example:

function reduce(array, combine, start) {
  var current = start;
  for (var i = 0; i < array.length; i++)
    current = combine(current, array[i]);
  return current;
}

console.log(reduce([1, 2, 3, 4], function(a, b) {
  return a + b;
}, 0));
// → 10

which when the for loop is re-written to include, what I thought were optional, curly braces, like:

function reduce(array, combine, start) {
  var current = start;
  for (var i = 0; i < array.length; i++) {
    current = combine(current, array[i]);
    return current;
  }
}

console.log(reduce([1, 2, 3, 4], function(a, b) {
  return a + b;
}, 0));
// → 1

the result is just 1 instead of the expected 10. What are the braces doing here to change the output?

Upvotes: 3

Views: 773

Answers (3)

Keeeenion
Keeeenion

Reputation: 31

This code runs the loop once and returns right after the first cycle:

for (var i = 0; i < array.length; i++) {
    current = combine(current, array[i]);
    return current;
}

Here we return after loop finishes cycling:

for (var i = 0; i < array.length; i++)
    current = combine(current, array[i]);
return current;

Upvotes: 3

Nina Scholz
Nina Scholz

Reputation: 386746

You need to move the return statement outside of the block for the for loop, because the return statement ends the function and the loop immediately.

for (var i = 0; i < array.length; i++) {
    current = combine(current, array[i]);
}
return current;

function reduce(array, combine, start) {
    var current = start;
    for (var i = 0; i < array.length; i++) {
        current = combine(current, array[i]);
    }
    return current;
}

console.log(reduce([1, 2, 3, 4], function(a, b) {
    return a + b;
}, 0));

Upvotes: 5

chaoticmite
chaoticmite

Reputation: 178

The curly braces are doing just as you asked of them: because you included the return statement in the for loop:

function reduce(array, combine, start) {
  var current = start;
  for (var i = 0; i < array.length; i++) {
    current = combine(current, array[i]);
    return current;
  }
}

the loop stops short of what was intended because the return exits the loop, actually function when a value is returned, and so only the value of the array's first element: 1 gets folded to var current and outputs 1. Whereas:

function reduce(array, combine, start) {
  var current = start;
  for (var i = 0; i < array.length; i++) {
    current = combine(current, array[i]);
  }
  return current;
}

returns the expected output: 10 because the for folds all array elements before returning a value.

Upvotes: 6

Related Questions