SBD
SBD

Reputation: 446

Javascript : The sum of its range

I'm currently following the exercises from Eloquent Javascript and got a little stuck at one exercise. Let me explain it with code:

var _numberArray = [];

function range(start, end, step) 
{
  console.log(_numberArray); 


  if (!step)
  {
    step = 1;
  }

  if (step < 0)
  {
     for(var i = start; i >= end; i -= step) 
     {
        _numberArray.push(i);
        console.log(_numberArray);


     }
  }
  else 
  {

     for(var i = start; i <= end; i += step) 
     {
        _numberArray.push(i);
        console.log(_numberArray);
     }
  }


    return _numberArray;
}


  function sum(array) 
  {
    var total = 0; 
    for (var i = 0; i < array.length; i++)
    {

        total += array[i];

    }
  return total;

}

console.log(sum(range(42,14,-2)));

So I created the range function where I check if the step argument has been set. If not, set the default step variable to 1. If step is smaller than 0, be sure to loop where as long as the first argument is bigger the second, and decrement the value with the step amount given. This is the same for incrementing.

However, this code causes to crash only when I use negative values. So when I do "sum(range(22,6,-2));" the code crashes. The other way round "sum(range(6,22,2));" it does work. Also when I replace:

  for(var i = start; i >= end; i -= step) 
         {
            _numberArray.push(i);
            console.log(_numberArray);


         }

For:

    for(var i = start; i >= end; i--) 
     {
        _numberArray.push(i);
        console.log(_numberArray);


     }

It does work again! Can someone help me out and give me some understanding why it crashed and why the last method does work?

Thanks.

Upvotes: 2

Views: 1560

Answers (3)

Cesar Perez
Cesar Perez

Reputation: 109

I came up with a solution to fix the problem with negative numbers and a negative step,also modified a bit the function so you don't have two for loops,instead just on while loop.

    function range(n1,n2,step){
      var start, end;
      var list = [];

    /*
    Function take two parameters and decides which will become 
    the start by comparing both and evaluating who is smaller.
    I used the ternary operator to test an expression if true
    the first option is applied else the second option.
    */
      (n1 > n2 ? (start = n2, end = n1):(start = n1, end = n2));
    //Check if step is null or zero
      if(step == null || step == 0)
        step = 1;
    /*
    Check if step is a negative number, if so convert it to a 
    postive number. Since the start will always be the smallest 
    number there is no need to subtract even if the var start and
    var end are both negative numbers
    */
      if(step < 0)
        step *= -1;
    // Use a while loop to push numbers into array    
      while(start <= end){
        list.push(start);
        start += step;
      }
    // Made sure the var end was always included at the end of the list    
      if(list.indexOf(end) == -1)
        list.push(end);

    // Return list and end program
    return list;
    }

    //funciton that adds up the list of numbers 

    function sum(array){
      var total = 0 ;
      for(var i = 0; i < array.length; i++){
        total += array[i];
      }
      return total;
    }

Upvotes: 0

briangri
briangri

Reputation: 1

if (step < 0)
   {
     for(var i = start; i >= end; i -= step)

If, say, step is negative 2, start is 22, end is 6:

i = 22, 22 >= 6, i = 22 - (-2)
i = 24, 24 >= 6, i = 24 - (-2)
i = 26...

It looks like you are accounting for the negative step twice (the step is negative, so you don't need to subtract it).

Upvotes: 0

McGarnagle
McGarnagle

Reputation: 102753

Since the step value is negative, and you're iterating downwards, you need to add it, not subtract it:

for(var i = start; i >= end; i += step) 

Subtracting a -2 is the same as adding 2, so you're going 42, 44, 46, ... And that value is always more than "end" (14), hence the infinite loop.

Upvotes: 2

Related Questions