Using Python range() in JavaScript
Tags: javascript, python, programming, webdev
Published: 2021-08-04 20:37:47

## What is the Python range() type?
If you’re not familiar with Python, `range()` refers to the use of the range type to create an immutable sequence of numbers.

> “The range type represents an immutable sequence of numbers and is commonly used for looping a specific number of times in for loops.” — [docs.python.org](https://docs.python.org/3/library/stdtypes.html#range)

The `range()` constructor has two forms of definition:
```
range(stop)
range(start, stop[, step])
```
A concise explanation of the parameters, return value, etc. can be found on [programiz](https://www.programiz.com/python-programming/methods/built-in/range).

A few examples:

{% gist https://gist.github.com/guyariely/2fd354b0aab64b4187dd894e2bedaa8b.js %}

## Building the range() function in JavaScript

For simplicity sake, we will ignore the optional `step` argument.

By using the `Array` constructor, `fill` and `map`, you could work out a simple solution in a quick one-liner:

```
new Array(stop - start).fill(start).map((el, i) => el + i)
```

And maybe then offer a more complete solution, covering the case of calling range with only one argument:

{% gist https://gist.github.com/guyariely/ee9e688e6f59131d15ffc7a43f6fcea4.js %}

But it’s _not_ quite it yet. Can you see why this solution is wrong?

Remember, calling Python `range` returns an **immutable sequence of numbers**. Notice how in order to get the familiar list data structure, the Python examples above wrap the return value of range with `list()`.

An equal example in JavaScript should probably look something like this:

```
> Array.from(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

So how can we make a function in JavaScript return an “immutable sequence of numbers”? Is there any way to achieve the same structure of the `range()` return value in JavaScript?

## Iterators to the rescue!

Iterators are wildly used in different programming languages to allow us to iterate over different data structures.

> “In JavaScript an iterator is an object which defines a sequence and potentially a return value upon its termination.” —[developer.mozilla.org](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)

Specifically in JavaScript, an iterator is any object which implements the [Iterator protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterator_protocol) by having a `next()` method that returns an object with two properties:
```
next() {
  ...
  return {
    value: // current value to be passed
    done: // did we finish iterating over the data structure?
  }
}
```
Using an iterator, you can provide your own logic on how to iterate. For example, here is a simple iterator that will skip every second item:

{% gist https://gist.github.com/guyariely/f0b2316c3030e3f6adba3b3e910649c3.js %}

More importantly, If we create an object that defines `[Symbol.iterator]` which returns that iterator, **we can get exactly the behavior we were looking for**:

{% gist https://gist.github.com/guyariely/4d6b4e425fc9a3d2ed940e9018c2f7c6.js %}

Play around with these examples and see what kind of interesting and useful iterators you can create 💪.

By now you can probably imagine how we might approach creating Python `range()` in JavaScript. This is how I implemented it:

{% gist https://gist.github.com/guyariely/ea771fbbf7ec3fcebf951f1ff01f84bc.js %}

As I mentioned, for simplicity's sake this implementation leaves out the `step` argument from the original Python `range()`, but it’s just a matter of extra logic that you can implement yourself. Feel free to @ me your solution ✌️.