Trouble with Array.from()

Hello guys,

I’ve been studying the Array.from() function on mozilla developer and am a bit confused on the sequence generator.

// Sequence generator function (commonly referred to as "range", e.g. Clojure, PHP etc)
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));

// Generate numbers range 0..4
range(0, 4, 1);
// [0, 1, 2, 3, 4] 

// Generate numbers range 1..10 with step of 2 
range(1, 10, 2); 
// [1, 3, 5, 7, 9]

Can somebody help me understand how the math works in this?

It says { length: (stop - start) / step + 1} for a range of (0 ,4, 1).

Doesn’t this make length: 2 when the length should be 5? [0,1,2,3,4]
What does the _ underscore represent?
And is i already preset to integer 1?

Operator precedence: division comes before addition.

It’s just the name of a parameter that it isn’t being used. The callback, which runs for every element in the newly created array, has as a first parameter the current element – that isn’t used, it’s the second parameter, the current index, which is being used. So the parameter has got to be there, it’s just a way of [visually] saying to the person reading the code “I just want to ignore this”

The underscore being used to represent an unused variable is something you’ll sometimes see in JS. Some other languages (Haskell, OCaml, Elixir, Go, Rust for example) use it to tell the compiler to ignore a parameter or value completely. It’s borrowed from there. It doesn’t quite work conceptually in JS because it isn’t a special thing at all, but it’s sometimes quite useful to explicitly show that you don’t care about one specific argument.

Completely forgot about precedence, and the current elements makes some more sense now. But what about the current index? Is this always automatically set to 1?

Nono – so the callback function runs for every element in the array, it loops:

(_, i) => start + (i * step)

Where i is the index of the current element in the loop.

So if you have 0, 4, 1: start is 0, step is 1:

First, you get an array of length 5:

[undefined, undefined, undefined, undefined, undefined]

First element is index 0: 0 + (0 * 1) is 0, replace first undefined.
Second element is index 1: 0 + (1 * 1) is 1, replace second undefined.
Third element is index 2: 0 + (2 * 1) is 2, replace third undefined.
Fourth element is index 3: 0 + (3 * 1) is 3, replace fourth undefined.
Fifth element is index 4: 0 + (4 * 1) is 4, replace fifth undefined.

And you can also see why the first parameter is ignored: the current value isn’t useful, because it’s just undefined for each one, but the index is useful, as it lets you use it to build a range of values

1 Like

Wow that clears up a lot for me. I should’ve known , the word “index” is literally in the term current index. It makes so much more sense now…
Thank you!!

1 Like