Captain Anunnaki
Captain Anunnaki

Reputation: 25

A range of numbers in js

So I wanted to make a recursive function that pushes a range of numbers inside of an array. So I did the following:

function rangeOfNumbers(startNum, endNum) {
  let arr = [];
  
  if (startNum != endNum) {
    rangeOfNumbers(startNum++, endNum);
    arr.push(startNum);
  } else {
    arr.push(endNum);
  }
  
  return arr;
};

console.log(rangeOfNumbers(1, 5));

so the way I think that should work is that in each iteration startNum should be +1 and should be pushed inside of the array and when startNum gets to endNum's value in this case 5 we should push endNum and end the recursion, why is my logic faulty, cuz what happens now is that my function exceeds the maximum call stack.

Another thing I tried was:

function rangeOfNumbers(startNum, endNum) {
  let arr = [];
  
  if (startNum == endNum) {
    return arr.push(endNum);
  } else {
    rangeOfNumbers(startNum++, endNum);
    arr.push(startNum);
  }
  
  return arr;
};

still exceeds the callstack, why does that happen? :(

Upvotes: 1

Views: 910

Answers (3)

pilchard
pilchard

Reputation: 12918

You are redefining your arr variable on every call, and never using the arrays returned from deeper calls. You can either pass a single array reference as Basto does in their answer, or you can run through the recursion and only define the array on the terminal call and then unshift() each startNum into the returned array.

function rangeOfNumbers(startNum, endNum) {
  const arr = startNum < endNum ? rangeOfNumbers(startNum + 1, endNum) : [];
  
  arr.unshift(startNum);

  return arr
};

console.log(rangeOfNumbers(1, 5));

unshift() is quite slow though. You can alter the logic to use push() by decrementing 'endNum' instead of incrementing 'startNum', and pushing 'endNum' on each call.

function rangeOfNumbers(startNum, endNum) {
  const arr = startNum < endNum ? rangeOfNumbers(startNum, endNum - 1) : [];

  arr.push(endNum);

  return arr
}

console.log(rangeOfNumbers(1, 5))

Or using spread syntax (...)

function rangeOfNumbers(startNum, endNum) {
  return startNum <= endNum
    ? [startNum, ...rangeOfNumbers(startNum + 1, endNum)]
    : [];
}

console.log(rangeOfNumbers(1, 5));

Upvotes: 2

Jazz
Jazz

Reputation: 341

You are only returning the array from the first iteration.

You need to make the array one of your arguments on your recursive function so all the pushes are into the same array

function rangeOfNumbers(startNum, endNum, arr =[]) {
    if(startNum < endNum) {
        arr.push(startNum);
        rangeOfNumbers(startNum + 1, endNum, arr);
    }else{
      arr.push(endNum);
    }
    return arr;
};

Edit: You probably also want to call the recursion after the push so they are all in order.

And I also changed the comparison operator to a < to prevent stack overload if the function is used wrong.

Upvotes: 1

Basto
Basto

Reputation: 216

You have to put the array in parameters :

let arr = [];

function rangeOfNumbers(startNum, endNum, arr) {
  if (startNum !== endNum) {
    arr.push(startNum);
    rangeOfNumbers(startNum + 1, endNum, arr);
  } else {
    arr.push(endNum);
  }

  return arr;
}

console.log(rangeOfNumbers(1, 5, arr));

Upvotes: 1

Related Questions