TC39 proposal for Object.fromEntries
Clone or download
Latest commit 825740a Oct 13, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.gitattributes Add template files Mar 11, 2018
.gitignore Add template files Mar 11, 2018
.npmrc Add template files Mar 11, 2018
DETAILS.md Fix typo in DETAILS Aug 23, 2018
LICENSE Add template files Mar 11, 2018
README.md Add author / champions to readme Mar 20, 2018
index.html [spac] link AddEntriesFromIterable Oct 13, 2018
package.json [Dev Deps] update `ecmarkup` Jul 11, 2018
polyfill.js General refactor / cleanup Mar 11, 2018
spec.html [spac] link AddEntriesFromIterable Oct 13, 2018

README.md

Object.fromEntries

A proposal for a new static method Object.fromEntries in ECMAScript for transforming a list of key-value pairs into an object.

This proposal was originally written by Darien Maillet Valentine and is being championed by Jordan Harband and Kevin Gibbons.

Proposal

Object.fromEntries is proposed to perform the reverse of Object.entries: it accepts an iterable of key-value pairs and returns a new object whose own keys and corresponding values are given by those pairs.

obj = Object.fromEntries([['a', 0], ['b', 1]]); // { a: 0, b: 1 }

See DETAILS.md for details.

Rationale

It's common to transform data held in various structures (arrays, maps, etc) from one form to another. When the data structures in question are both iterable this is typically simple:

map = new Map().set('foo', true).set('bar', false);
arr = Array.from(map);
set = new Set(map.values());

The iterable entries of a Map take the form of key-value pairs. This dovetails nicely with the pairs returned by Object.entries, such that you can convert objects to Maps fairly expressively:

obj = { foo: true, bar: false };
map = new Map(Object.entries(obj));

However there is no inverse of Object.entries for constructing objects from key-value pairs, so to do so one typically must write a helper or inline reducer:

obj = Array.from(map).reduce((acc, [ key, val ]) => Object.assign(acc, { [key]: val }), {});

This can be written many different ways, and potentially adds noise because it's not likely to be obviously related to the outward purpose of the function doing it.

Motivating examples

Object-to-object property transformations

This allows the easy use of familiar array manipulation methods to transform objects:

obj = { abc: 1, def: 2, ghij: 3 };
res = Object.fromEntries(
  Object.entries(obj)
  .filter(([ key, val ]) => key.length === 3)
  .map(([ key, val ]) => [ key, val * 2 ])
);

// res is { 'abc': 2, 'def': 4 }

Object from existing collection

A string-keyed Map can be converted to an object, just as an object can already be converted to a Map:

map = new Map([ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]);
obj = Object.fromEntries(map);

// compare existing functionality: new Map(Object.entries(obj))

This transformation may be simple for other Map-like objects as well:

query = Object.fromEntries(new URLSearchParams('foo=bar&baz=qux'));

For other collections, intermediate transformations can put the collection in the required form:

arr = [ { name: 'Alice', age: 40 }, { name: 'Bob', age: 36 } ];
obj = Object.fromEntries(arr.map(({ name, age }) => [ name, age ]));

Prior art

Lodash

Underscore and Lodash provide a _.fromPairs function which constructs an object from a list of key-value pairs.

Python

In Python, a dict can be initialized with an array of key-value tuples:

dict([('two', 2), ('one', 1), ('three', 3)])