DEV Community

Here's Why Mapping a Constructed Array in JavaScript Doesn't Work

Shawn Reisner on June 15, 2018

Why Mapping a Constructed Array Doesn’t Work in JavaScript And How To Do It Correctly Scenario For the sake of...
Collapse
 
elarcis profile image
Elarcis • Edited
Array.from({ length: 100 }, (_, i) => i);
Collapse
 
loilo profile image
Florian Reuschel

Whaaat.

I'm honestly baffled. Used Array.from() so often but never knew about the mapping argument. Well, today I learned. Thank you!

Collapse
 
sreisner profile image
Shawn Reisner

Well I'll be... Nice!

Collapse
 
jbristow profile image
Jon Bristow • Edited

Why not just [...Array(5).keys()];?

For history’s sake, it’s equivalent to:

Array.apply(null, Array(5)).map(function(_, i) {
  return i;
});
Collapse
 
thorstenhirsch profile image
Thorsten Hirsch • Edited

Shawn's point was not to find a solution that does not use a for loop. Shawn's point was to demonstrate why the code that one would expect to work does not:

Array(100).map((_, i) => i)

It looks simple, but does not work in Javascript, due to this array-is-an-object thingy. That's the point.

I'm not sure if I would go with Shawn's spread operator solution or if I'd just go back to a simple for loop. But I'm pretty sure that Array.apply(null, ...) and Elarcis' Array.from(...) are not solutions that are easy to understand (no offence), they both seem to be workarounds.

Collapse
 
loilo profile image
Florian Reuschel • Edited

To be honest, with regard to the article, I find it quite weird that Array(5).keys() does work. 🤔

Thread Thread
 
jbristow profile image
Jon Bristow

It doesn’t!

The ... fires first and produces Array.apply(null, Array(5)).keys()

Then that is expanded to Array(undefined, undefined, undefined, undefined, undefined).keys().

Since the Array was created by a list of items, keys returns [0,1,2,3,4]

JavaScript needs a range operator or a Texas range notation. Just so I don’t need to hide the splat under a function to increase readability.

Thread Thread
 
loilo profile image
Florian Reuschel

Makes sense, thanks. I struggle with splat operator execution order from time to time.

Thread Thread
 
jbristow profile image
Jon Bristow

In trying to rewrite the above code I ended up having to experiment a bit to figure out what was happening when... it’s certainly far from obvious.

Collapse
 
sreisner profile image
Shawn Reisner

This also works!

Collapse
 
ann0nip profile image
Juan Martin Gimenez

I think my question is out of the scope of the topic, but:

When we do:


Array(100);

If there are no index keys in the object representation of the array (the object is a vacuum), why we can spread it?? 🤯


const arr = [...Array(100)]

Thank you for this interesting post!

Salute from 🇦🇷!

Collapse
 
sreisner profile image
Shawn Reisner • Edited

Great question. The reason we can spread an array with no index keys is because spread's implementation doesn't require that any index keys exist, unlike map. It blindly loops from 0 to 99, asks the array for array[index], and places whatever's returned in the new array.

Collapse
 
belinde profile image
Franco Traversaro

I know this isn't a constructive comment, but... How the heck a map on a deconstructed array with an anonymous function can be more appealing then a for loop? Really, I don't want to start a flame, I just don't understand.

Collapse
 
sreisner profile image
Shawn Reisner

The for loop is an appealing construct. It's simple. You understand exactly what's happening algorithmically without much of a second thought. The appeal of the higher order map function is that it abstracts away the algorithmic details so that you're telling the code what to, not how to do it. In my experience, code written this way is easier to understand, debug, and maintain, and generally produces fewer bugs. This becomes more true when we need to chain the effects of these higher order functions, but even in cases like this we still benefit from the fact that there's almost nowhere for a bug to hide.

Collapse
 
belinde profile image
Franco Traversaro

I don't agree... You know, you've just written an article about this approach not working with a naive approach 😁

That was obviously a joke, but still for me it's very hard to understand what that code do. And I feel a bit of horror thinking about the CPU cycles wasted with so many calls...

Thread Thread
 
sreisner profile image
Shawn Reisner

Not quite. I added the bit about the for loop being perfectly fine at the beginning of the article on purpose - because it is! I'm glad you found it thought provoking. I appreciate the feedback! ❤️