Array.from - more powerful than you think
Array.from is a JavaScript function that until now, I've used exclusively to transform an iterable into an array. I had never considered the powerful factory functionality that it provides, because its declared signature is deceptively simple: Array.from(arrayLike, mapFn, thisArg)
. So you get something that's like an array (an interable, right?) then you map it (phaw, like I don't know how to map an array!) and a thisArg probably sets the this context for the function (like I don't know how to bind a function!)
And yet...
The first "array-like" parameter doesn't need to be an iterable, it can be an object with a length. Meaning that you can just do something a number of times.
Example for creating a range:
// Sequence generator function (commonly referred to as "range", cf. Python, Clojure, etc.)
const range = (start, stop, step) =>
Array.from(
{ length: Math.ceil((stop - start) / step) },
(_, i) => start + i * step,
);
Getting a sample from an array of string:
const sample = (arr, count) =>
Array.from(
{ length: count },
()=>arr[Math.floor(Math.random()*arr.length)]
);
How about generating a random string?
const chars = 'abcdefghijklmnopqrstuvwxyz';
const randomString = (length) =>
Array.from({ length }, () => chars[Math.floor(Math.random() * chars.length)]).join('');
// OR using the sample function above
const randomString = (length) =>
sample('abcdefghijklmnopqrstuvwxyz',length).join('');
And if you don't want an array, but something "array-like", like a NodeList?
class MyClass {}
Array.from.call(MyClass, ["foo", "bar", "baz"]);
// MyClass {0: 'foo', 1: 'bar', 2: 'baz', length: 3}
I admit Array.from(a,b,c)
is functionally equivalent to Array.from(a).map(b.bind(c))
, but it's more efficient, as the array is constructed only once. The power of this function comes from its interpretation of the "array-like" first argument. It takes iterable objects and/or containing a length property, thus allowing a more concise, functional way of writing code and avoiding unnecessary loops.
Hope it helps!
Comments
Be the first to post a comment