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 Maps and Sets, 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:

  1. Its syntax is more readable
  2. 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!

Resources


Subscribe for the latest news

Sign up for my mailing list to get the latest blog posts and content from me. Unsubscribe anytime.