With 2019 sure underway, we’re here to dive into the new ES2019 features in the JavaScript language! Some new operators are now available to us, so if you’ve never used flat()
, flatMap()
or fromEntries()
then this post is for you to learn ES2019 features from real code examples!
JavaScript is standardized by a scripting-language specification called ECMAScript (or ES for short). The newest version of ES was published in January 2019 and is named ECMAScript2019 (ES2019). In this article, I will present an ES2019 feature-set that will help you in your daily work as a JavaScript developer. So let’s dive in to dealing with data structures and see how the new features can help us!
Table of contents
Flattening Arrays
The flat() method
First, let’s talk about Flattening Arrays in JavaScript! Methods flat()
and flatMap()
allows you to concatenate multidimensional arrays into a single array - this is the definition of ‘flatten’. This will make our data structure easier to work with.
Take a look at the first example to understand how the flat()
method works:
[['🐵', ], ['Flattened!', '🙊'], ['🙈', '🙉']].flat();
// output: (5) ["🐵", "Flattened!", "🙊", "🙈", "🙉"]
So, what’s happening here? Initially, we had 3-elements in our array and each element consisted of an array containing strings. The first sub-array included one empty element as well so we can see the effects flat()
has. As a result, we created a single array that stores 5 elements. In other words, we reduced one dimension of the array and removed empty slots.
Let’s improve the input object to test more behavior. We will replace the middle array with a two-dimensional array. After that, we will flat it the same way as before:
[['🐵', ], [['Flattened','!'], '🙊'], ['🙈', '🙉']].flat();
// output: (5) ["🐵", Array(2), "🙊", "🙈", "🙉"]
As you can see above, we didn’t get a one-dimensional array - why? Let me introduce an optional parameter for the flat()
method, “depth”, meaning how deep a nested array will be flattened. As a default, using flat()
will reduce to one dimension (depth parameter set to `1`).
Let’s specify the depth level for the array and merge the object into a one-dimensional array:
[['🐵', ], [['Flattened','!'], '🙊'], ['🙈', '🙉']].flat(2);
// output: (6) ["🐵", "Flattened", "!", "🙊", "🙈", "🙉"]
We set depth to `2`, and we achieved our goal. We created a new single array which now contains six elements.
The flatMap() method
After the introduction to Flattening Arrays, we will look closer at the flatMap()
method. To be brief, this function works like a combination of the flat() and map() methods. It allows us to transform data in an array and concatenate multidimensional arrays into a one-dimensional array in one operation.
Free eBook
Directives, simple right? Wrong! On the outside they look simple, but even skilled Angular devs haven’t grasped every concept in this eBook.
- Observables and Async Pipe
- Identity Checking and Performance
- Web Components <ng-template> syntax
- <ng-container> and Observable Composition
- Advanced Rendering Patterns
- Setters and Getters for Styles and Class Bindings
Heading to our initial example, we’ll use the same array but additionally, we want to operate on array data instead of just flattening it, we’ll be in charge of what happens.
Let’s replace the flat()
method with the flatMap()
and add a callback function that produces an element with the expected result. it’s important to note that flatMap()
expects a function as the argument. The flatMap()
method is useful when we operate on the array data and its dimensions. It means that a result of the mapping function is an array with reduced depth level.
Take a look below, I’ve also included map()
so we can see something interesting:
const array = [['🐵', ], ['Flattened!', '🙊'], ['🙈', '🙉']];
array.flatMap((element, index) => index + ': ' + element);
// output: (3) ["0: 🐵", "1: Flattened!,🙊", "2: 🙈,🙉"];
array.map((element, index) => index + ': ' + element);
// output: (3) ["0: 🐵", "1: Flattened!,🙊", "2: 🙈,🙉"];
The effect of flatMap()
and map()
is the same. Let’s analyze another case to understand the difference between flatMap()
and map()
.
In the current example, we want to mix indexes with array elements. Therefore, we will map each of the elements to a new array that stores an index and element data. Let’s compare the result of flatMap()
and map()
methods:
const array = [['🐵', ], ['Flattened!', '🙊'], ['🙈', '🙉']];
array.flatMap((element, index) => [index, element]);
// output: (6) [0, Array(1), 1, Array(2), 2, Array(2)]
array.map((element, index) => [index, element]);
// output: (3) [Array(2), Array(2), Array(2)]
Now you can see the difference - the dimension of the output array. The flatMap()
method allows you to decrease one depth level for the result object.
However, there’s no possibility to use a parameter to specify how deep a nested array will be flattened. So how do we manipulate this level manually? Just apply the flat()
method on the output:
const array = [['🐵', ], ['Flattened!', '🙊'], ['🙈', '🙉']];
array.flatMap((element, index) => [index, element]).flat();
// output: (8) [0, "🐵", 1, "Flattened!", "🙊", 2, "🙈", "🙉"]
Trim operations
Secondly, in ES2019 feature set, we can find a method to deal with trimming off whitespace. The previous standardized function that allows you to remove whitespace from string was published in ES5. The trim()
method deletes whitespace from both sides of a string variable, whereas now we can trim from a specific side (start of end of the string), which leads us to trimStart()
and trimEnd()
…
trimStart() and trimEnd()
Let’s try using trimStart()
and see what it gives us!
(' Hello 👋🏻 Dev! ').trimStart();
// output: "Hello 👋🏻 Dev! "
If you want to delete whitespace at the end of String, apply the trimEnd()
method:
(' Hello 👋🏻 Dev! ').trimEnd();
// output: " Hello 👋🏻 Dev!"
Masterclass over. These methods are fairly simple and there’s not much more to them!
trimLeft() and trimRight()
In addition, methods trimRight()
and trimLeft()
work the same way. The trimLeft()
method does the same as trimStart()
, the trimRight()
method is a twin for the trimEnd()
:
(' Hello 👋🏻 Dev! ').trimRight();
// output: " Hello 👋🏻 Dev!"
(' Hello 👋🏻 Dev! ').trimLeft();
// output: "Hello 👋🏻 Dev!"
Creating Object from entries
Last but not least, we will play with creating Objects from entries, and this feature is really nice. The fromEntries()
method turns a list of key-value pairs into a new object whose properties come from those entries. This method takes one parameter called iterable. This is an object implementing the iterable protocol (but that’s for another day…). Particularly we use Array or Map as an entry:
Let’s create an object from a multidimensional Array:
const array = [['flower', '🌷'],['animal', '🐹']];
Object.fromEntries(array);
// output: {flower: "🌷", animal: "🐹"}
As a result, we initialized a new Object with two keys (flower, animal). Every key has a set of value from an initial Array with key-value pairs.
If you’re into using Map
then we can also use fromEntries()
:
const map = new Map([['flower', '🌷'], ['animal', '🐹']]);
Object.fromEntries(map);
// output: {flower: "🌷", animal: "🐹"}
It’s also interesting to see what happens if we add duplicate keys to an array and transform it into an object using the fromEntries() method:
const array = [['animal', '🐹'],['flower', '🌷'], ['animal', '😺']]);
// output: (3) [Array(2), Array(2), Array(2)]
Object.fromEntries(array);
// output: {flower: "🌷", animal: "😺"}
Accordingly, the value for the duplicated key comes from the last element in the array, and really we should expect this as it’s processed last and therefore will be overwritten. Above all, it behaves like a transformation to Map and then converting into a new object. Follow and compare this example for Map:
const map = new Map[['animal', '🐹'],['flower', '🌷'], ['animal', '😺']]);
// output: Map(2) {"animal" => "😺", "flower" => "🌷"}
Object.fromEntries(map);
// output: {flower: "🌷", animal: "😺"}
Conclusion
To sum up, in this article I showed you major new features released in the final version of ECMAScript2019. I analyzed flattening Arrays (flat()
, flatMap()
methods), ways to trim whitespaces from String variables and a process of creating Objects from entries. I hope it will be helpful for you. Start using those methods in your code, however remember to check browser compatibility for the features you want to apply (I would recommend using Babel, which you can learn more about in our JavaScript Courses course).
Thanks for reaching and have a nice day! 👋🏻