简体   繁体   中英

Eloquent JavaScript book exercise function sum of range

The sum of a range

Write a range function that takes two arguments, start and end, and returns an array containing all the numbers from start up to (and including) end.

Modify your range function to take an optional third argument that indicates the “step” value used when building the array. If no step is given, the elements go up by increments of one, corresponding to the old behavior. The function call range(1, 10, 2) should return [1, 3, 5, 7, 9]. Make sure it also works with negative step values so that range(5, 2, -1) produces [5, 4, 3, 2].

Book solution:

function range(start, end, step) {
      if (step == null) step = 1;
      var array = [];
    
      if (step > 0) {
        for (var i = start; i <= end; i += step)
          array.push(i);
      } else {
        for (var i = start; i >= end; i += step)
          array.push(i);
      }
      return array;
    }

console.log (range(1,10,2))
// → [1, 3, 5, 7, 9]
console.log(range(5, 2, -1));
// → [5, 4, 3, 2]

But this solution doesn't work with any start and end value.

Example:

console.log (range(1,10,-1))
// → []

Is anyone encouraged to modify code and explain steps in detail so that it works with any positive or negative start, end and step values? Tks

Try this:

 if(start < end && step < 0) { [start, end] = [end, start] }

Add this snipet inside your function, when start is lower than end and step is negative, then invert the values of start and end.

 function range(start, end, step) { if(start < end && step < 0) { [start, end] = [end, start] } if (step == null) step = 1; var array = []; if (step > 0) { for (var i = start; i <= end; i += step) array.push(i); } else { for (var i = start; i >= end; i += step) array.push(i); } return array; } console.log (range(1, 10, 2)); // → [1, 3, 5, 7, 9] console.log(range(5, 2, -1)); // → [5, 4, 3, 2] console.log (range(1, 10, -1)); // → [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

This function assumes - start should be greater than end when step is negative. So, your input is kind of Invalid Input.

Actually, saying it Invalid Input would be wrong, its basic math when you start from 1 and start decrementing by -1 you are never going to reach - 10 .

If you want to handle such cases, you can do by swapping start and end in case step is negative and start is less than end.

ie By adding these lines at the top.

if(start < end && step < 0) {
   [start, end] = [end, start]
}

But then saying them start and end would be kind of wrong.

When you call the function what those parameters, this is what happens:

  1. Step is a negative value, so it uses the second for loop (inside the else block)
  2. Then, this for loop runs while i is greater than or equal to the end value

However, since i is set equal to 1 as the start value, and the end is set to be 10, the loop will never run, since i is smaller than the end value. This means that i >= end will evaluate to false right from the beginning, and the loop will never start.

You just need to set a default value. That's all.

  function range(start, end, step=1) { 
let array = [];

  if (step > 0) {
    for (var i = start; i <= end; i += step)
      array.push(i);
  } else {
    for (var i = start; i >= end; i += step)
      array.push(i);
  }
  return array;
}
console.log (range(1,10,2))

console.log(range(5, 2, -1));

Change your example to:

console.log(range(10, 1, -1));

because start should be greater than end when step is negative.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM