Hi everyone! And welcome to another exciting edition of Boring JavaScript! Today, we tackle the Array.from() method – a quick and convenient way to create an array from any iterable object.
Don’t like to read? Then watch the video.
From Here to Eternity
Array.from takes two arguments – an iterable object and a callback function that gets called through each iteration. Let’s look at the first argument – uh – first.
Array.from works by taking the first argument and attempting to copy it into an array. The first argument can be any iterable object or an array-like object- meaning that there must exist a ‘length’ property and indexed elements (array-like) or have iteration methods as part of the object (Set and Map).
Let’s take a look at these examples:
const myCharacters = Array.from('Fluffy');
console.log(myCharacters);
const myArray = Array.from([ 1, 2, 3, 4]);
console.log(myArray);
const myNodeElements = Array.from(document.querySelectorAll('a')));
console.log(myNodeElements);
/* output
[ 'F', 'l', 'u', 'f', 'f', 'y' ]
[ 1, 2, 3, 4 ]
[ <a>, <a>, <a>, ..., <a> ]
*/
A string has a ‘length’ property and indexed items (the characters themselves). Therefore, it qualifies as an ‘array-type’ object, and Array.from() will copy each character as an element within in new array.
An array is an ‘array-like’ object (duh), so it to can be copied into a new array. Why would you want to do this? Look at the second section to find out.
Finally, a NodeList (returned by ‘querySelectorAll’) is also ‘array-like’, which means the results of your query can now be manipulated as if it is an array.
Consider now this code:
console.log('------------------- map -------------------')
const myMap = new Map();
myMap.set('cat', 'Fluffy');
myMap.set('dog', 'Rover');
myMap.set('lizard', 'Larry');
const myArrayMap = Array.from(myMap);
console.log(myArrayMap);
console.log(Array.from(myMap.keys()));
console.log(Array.from(myMap.values()));
console.log('------------------- set -------------------')
const mySet = new Set();
mySet.add('Fluffy');
mySet.add('Rover');
mySet.add('Larry');
const myArraySet = Array.from(mySet);
console.log(myArraySet);
/* output
------------------- map -------------------
[ [ 'cat', 'Fluffy' ], [ 'dog', 'Rover' ], [ 'lizard', 'Larry' ] ]
[ 'cat', 'dog', 'lizard' ]
[ 'Fluffy', 'Rover', 'Larry' ]
------------------- set -------------------
[ 'Fluffy', 'Rover', 'Larry' ]
*/
Since both Map() and Set() can be iterated, they can be copied into arrays with Array.from(). Notice that with both keys and values, Map() will return an array for each entry when being iterated. Therefore, you can use the Map.keys() method or the Map.values() method to get an iterable list of keys and values, respectively.
Function, Function, What’s Your Function?
The second argument to Array.from() is a callback function that gets applied to each iterable element, and the results of that function will be the value pushed to the new array. The function works exactly like the Array.map() method – except that only the value and index are passed as arguments.
Why would you need to do this? There will be many times that you will need to manipulate data in some way while you are copying it. What better way to do that than during the copy process itself?
For example, let’s say that you have a listing of animals contained within a Map. You want to convert this into an Array (why? Because we can!), but also convert the weight of the animals from kilograms to pounds. The function argument of Array.from() makes this easy.
console.log('------------------- map -------------------')
const myMap = new Map();
myMap.set('cat', { name: 'Fluffy', weight: 4.5 });
myMap.set('dog', { name: 'Rover', weight: 24.7 });
myMap.set('lizard', { name: 'Larry', weight: .75 });
const myArrayMap = Array.from(myMap, (animal, index) => {
let [ key, value ] = animal;
let { name, weight } = value;
weight *= 2.20462;
return { type: key, name, weight };
});
console.log(myArrayMap);
/* output
------------------- map -------------------
[
{ type: 'cat', name: 'Fluffy', weight: 9.920789999999998 },
{ type: 'dog', name: 'Rover', weight: 54.454114 },
{ type: 'lizard', name: 'Larry', weight: 1.6534649999999997 }
]
*/
Lines 6 through 11 is the function. Line 6 is our Array.from(), and as you can see we’re passing a function to it as the second argument. We expect two arguments in this function, the value of the iteration and the index itself.
Line 7 extracts the key and value from the animal. This is because we are iterating over a Map(), and a Map will pass the key/value pair in the form of an array.
Line 8 extracts the name and the weight from the animal, we convert the weight to pounds, then return a simple object that contains the type of animal (from the key), the name, and the weight in pounds.
The Video
Here is a video we’ve done on the subject:
Shameless Plug
We are everywhere!
Check out all our videos at: https://www.boringjavascript.com
Check out everything at: https://www.thevirtuoid.com
Facebook: https://www.facebook.com/TheVirtuoid
Twitter: https://twitter.com/TheVirtuoid
YouTube: https://www.youtube.com/channel/UCKZ7CV6fI7xlh7zIE9TWqgw
Categories: Boring JavaScript Javascript
thevirtuoid
Web Tinkerer. No, not like Tinkerbell.
Creator of the game Virtuoid. Boring JavaScript. Visit us at thevirtuoid.com
Leave a Reply