Range Class
Tags: javascript, beginners, tutorial
Published: 2020-02-10 06:43:42

Welcome coders, gamers, and all the other unique groups of people out there in the world. I'm here to discuss another code challenge called Range Class. Build a Range class that exposes functionality for dealing with ranges of numbers.

Build a Range class that exposes functionality for dealing with ranges of numbers.

The constructor should have the following characteristics: 
a beginning index,
an optional end index,
If there is no end index, the range should include only the passed-in start value.

an optional step,
The step is the interval at which elements are included. For instance, a step of 1 includes every element in the range, while a step of 2 includes every other element.

It should also include the following functions:

Size method that returns the number of items represented by the range

Each method takes a callback which takes an index. Iterate over the range, passing each value to a callback function.

Includes method which rakes an index and returns whether or not the range includes the passed value.

You should also be aware of the following caveats:

You should allow a negative value for 'step' to count backwards.
If no step is provided, it should default to 1.
If the start value is greater than the end value, assume we're counting backwards.

Should return null if we are given no 'start' value.
Range should use constant space, even during the each method. i.e. you should not use an Array as backing storage. 
Any given range could potentially be thousands of numbers long,
so find a way to represent the range without actually storing each element.

Okay so now that we have an understanding of what it should do let's look at the code. 

```javascript
const Range = function(start, end, step) {
  this.start = start;
  this.end = end === undefined ? start : end;
  this.step = !step ? (end > start ? 1 : -1) : step;
};

Range.prototype.each = function(callback) {
  for (let i = 0; i < this.size(); i++) {
    callback(this.start + this.step * i);
  }
};

Range.prototype.size = function() {   
  return Math.floor((this.end - this.start) / this.step) + 1;
};

Range.prototype.includes = function(target) {
  let included = false;
  this.each(num => {
    if(num === target){
      included = true;
    }
  });
  return included;
};

```
As I talk through the code I'll try and explain the variations of how both versions work. with that aside either version we have to start by doing the same thing. So we start off by setting our start, end, step on the constructor. The little difference for the short version is that we do a couple of helpful checks. So if our end is undefined we copy the value of our start so that it only runs once. If not then we set it to what end was passed in as. Next, when we get to our step we do a bit extra so if the user does not pass in a step we want to then use another conditional see if we need to go backwards or forward hence setting step either to one(1) or a negative one(-1). If a step was given by the user then we want to just use that one instead. 

Next, we have to implement our Each method, we can start by looping through the current size of our range. From there we take our callback and just call it on every single index. Man, that was pretty straight forward it's nice to be able to just call a function inside of a for loop and a pretty interesting thing on its own. 

For the size, we have a nice use of the Math.floor method that's just gonna take our end and start and perform the equation and return the largest integer less than or equal to our given number. then we add 1 to that.

Man, it's super unluckly I need to hit 3 minutes and must finish off discussing all parts of this thing. Sorry readers just need to stretch a little more out. 

Anyways now that we have done that, let's talk about the last method includes.
So in the code snippet above, we create a flag variable to be changed depending on our findings. So we call our Each function to test each element and check if it finds our target if it does we just change our flag variable to true else we do nothing we just return our flag variable.

Now usually I like to give a good outro so I'm tired therefore I won't finish.