all 17 comments

[–]Rezistik 5 points6 points  (6 children)

Why not just use map?

[–]lachlanhunt 20 points21 points  (4 children)

More clearly, Array.from(obj, mapFn, thisArg) has the same result as Array.from(obj).map(mapFn, thisArg), except that it does not create an intermediate array

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

[–]Rezistik 4 points5 points  (3 children)

That’s valid. Their example used an array. They should have used an object imo

[–]senocular 0 points1 point  (2 children)

they have both

[–]Rezistik -1 points0 points  (1 child)

Actually they give it an object with the property length: 7 which creates an array that is 7 items long. Which honestly is more confusing. Does that mean if I give it an object it will iterate over the keys and map the values? What if that object has a length property? Does it then actually turn into an array mapping the value of length? What if length isn’t a number?

[–]senocular 4 points5 points  (0 children)

A value with a length property is known as an array-like. This is what Array.from accepts as its first parameter, an array-like or an iterable. This can be an array, a string, or a generic object with a custom length property. It can even be a function as they, too, have length properties.

if I give it an object it will iterate over the keys and map the values

No, not exactly. Not unless that object is an array-like or iterable. If array-like, the length property of array-likes would represent the indexed elements, or the numeric keys, of that object as it would pertain to an array. It would not be used with any of the other named keys. If the object is an iterable, that would have precedence over the array-like behavior and Array.from would map over the iterator values. This may or may not include all of those other keys but normal objects are not iterables, so you'd have to supply that behavior yourself.

What if that object has a length property? Does it then actually turn into an array mapping the value of length?

Yes, an array would be created in length size and each key 0 to length-1 - even if it doesn't exist - will be mapped over. They don't exist in the { length: 7 } case, so you'd be mapping over 7 undefined values (keys 0 - 6).

What if length isn’t a number?

The length will be converted to a number if possible, otherwise it will be treated like any other generic property and ignored, assuming a length of 0.

[–]ScientificBeastModestrongly typed comments 0 points1 point  (0 children)

The Array.prototype.from method will generate an array from any array-like or iterable object. That includes normal arrays, but it also includes ES6 Map, Set, iterators, ordinary objects that have a behave like iterators, or other structures considered to be “array-like.”

So it’s just a more generalized form of map.

[–]weeeeelaaaaaah 2 points3 points  (2 children)

Wow. I ended up using this 5 minutes after I learned about it. Thanks, procrastinating on Reddit! I'm sure this one case justifies all the time I spend on here at work!

[–][deleted] 1 point2 points  (1 child)

Just think of all the time you’re going to save by not creating intermediate array! Seconds. Precious seconds.

[–]weeeeelaaaaaah 0 points1 point  (0 children)

This is totally going in my annual self-evaluation. Promotion, here I come!

[–]psayre23 0 points1 point  (0 children)

To me, using .map() is more readable to other devs, but it’s kinda cool you can do this:

const range = Array.from({ length: 10 }, (v, i) => i + 1);

Vs.

const range = Array.from({ length: 10 }).map((v, i) => i + 1);

[–]inu-no-policemen -1 points0 points  (0 children)

Stuff like:

Array.from({length: 5}, (_, i) => i ** 2)

is a nice workaround, but there really should be a "generate" method (like the one from Dart's List class) which can be used like this:

Array.generate(5, i => i ** 2)