How to convert an array to an object in JavaScript with Object.fromEntries
Suppose you have a list of key-values pairs like this:
const songs = [
[1, { artist: 'Smash Mouth', title: 'All Star' }],
[2, { artist: 'Counting Crows', title: 'Accidentally In Love' }],
[3, { artist: 'Bonnie Tyler', title: 'Holding Out for a Hero' }],
];
Your goal is to turn it into an object like this:
const songIdToMetadata = {
1: { artist: 'Smash Mouth', title: 'All Star' },
2: { artist: 'Counting Crows', title: 'Accidentally In Love' },
3: { artist: 'Bonnie Tyler', title: 'Holding Out for a Hero' },
};
In this post, you’ll learn how to solve this with Object.fromEntries
and why you’d want to use it instead of .reduce
.
Object.fromEntries
Object.fromEntries
takes an iterable of key-value pairs and creates a new object. The key of each pair (the first item) is used as a property key of the new object and the value (the second item) is the new property key’s value. This is the reverse of Object.entries
.
You can use Object.fromEntries
to cleanly create an object from an array of key-value pairs:
const songs = [
[1, { artist: 'Smash Mouth', title: 'All Star' }],
[2, { artist: 'Counting Crows', title: 'Accidentally In Love' }],
[3, { artist: 'Bonnie Tyler', title: 'Holding Out for a Hero' }],
];
const songIdToMetadata = Object.fromEntries(songs);
console.log(songIdToMetadata);
/*
{
'1': { artist: 'Smash Mouth', title: 'All Star' },
'2': { artist: 'Counting Crows', title: 'Accidentally In Love' },
'3': { artist: 'Bonnie Tyler', title: 'Holding Out for a Hero' }
}
*/
Other iterables of key-value pairs, such as Map
s and Set
s, work as well:
const x = new Set([
[1, 'a'],
[2, 'b'],
[3, 'c'],
]);
const y = Object.fromEntries(x);
console.log(y); // { '1': 'a', '2': 'b', '3': 'c' }
Turning a list of objects into one object
Object.fromEntries
is also useful when you have a list of objects and you want to turn them into one object. For each object in the list, one of its properties is added to the new object and the property’s value is the rest (or part of) of the object.
For example, say you have a list of song objects instead of key-value pairs:
const songs = [
{ id: 1, artist: 'Smash Mouth', title: 'All Star' },
{ id: 2, artist: 'Counting Crows', title: 'Accidentally In Love' },
{ id: 3, artist: 'Bonnie Tyler', title: 'Holding Out for a Hero' },
];
You want to turn this into the same songIdToMetadata
object from earlier, so you can first create a list of [id, metadata]
pairs and pass it to Object.fromEntries
:
const songEntries = songs.map(({ id, ...metadata }) => [id, metadata]);
const songIdToMetadata = Object.fromEntries(songEntries);
Object.fromEntries vs .reduce
Recall the original songs
array from above:
const songs = [
[1, { artist: 'Smash Mouth', title: 'All Star' }],
[2, { artist: 'Counting Crows', title: 'Accidentally In Love' }],
[3, { artist: 'Bonnie Tyler', title: 'Holding Out for a Hero' }],
];
Another way you could create songIdToMetadata
is with .reduce
and an object spread:
const songIdToMetadata = songs.reduce(
(acc, [id, metadata]) => ({ ...acc, [id]: metadata }),
{}
);
Compare it again with the Object.fromEntries
version:
const songIdToMetadata = Object.fromEntries(songs);
There are two reasons I’d prefer to use Object.fromEntries
here:
- Its syntax is more readable
- It’s more performant
First, the .reduce
syntax above took me ~1 minute to write correctly because of all the parentheses and braces; the Object.fromEntries
syntax is much cleaner.
Second, each iteration of the .reduce
creates a new object via the spread operator with the previous properties and the new property. On the first iteration, this creates a new object with one property; on the next, an object with two properties, and so on.
This means that the .reduce
method with the object spread has a time complexity of O(n^2), while Object.fromEntries
is O(n). You can compare the performance of these two object-building methods in the chart below 😬:
The benchmarking script used to generate this chart was written by and provided to me by Alex Iadicicco. Thanks, Alex!
Conclusion
Object.fromEntries
is a handy way to create an object from an iterable of key-value pairs. Consider using it the next time you’re building an object from an array, and prefer it over .reduce
.
Acknowledgements
Thanks to Alex Iadicicco for teaching me about Object.fromEntries
and for sharing his performance data.
Let's connect
Come connect with me on LinkedIn, Twitter, and GitHub!
If you found this post helpful, please consider supporting my work financially:
☕️Buy me a coffee!