unicorn/prefer-object-from-entries

Require Object.fromEntries() to turn key-value pairs into an object

Building an object with reduce and a spread copies the whole object on every step, so the work grows with the square of the number of items. Object.fromEntries() does it in one pass and says what the code is for.

The rule reports a reduce that starts from {} or Object.create(null). The callback must be an arrow function without a block body that returns { ...result, key: value } or Object.assign(result, { key: value }). It also reports _.fromPairs() and lodash.fromPairs().

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"unicorn/prefer-object-from-entries" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"unicorn/prefer-object-from-entries" = ["error", {
  functions = ["_.fromPairs", "lodash.fromPairs"],
}]

Examples#

example.js3 problems
const byId = users.reduce((result, user) => ({ ...result, [user.id]: user }), {});

const ages = users.reduce((result, user) => Object.assign(result, { [user.name]: user.age }), {});

const query = _.fromPairs(pairs);
example.jsNo problems
const byId = Object.fromEntries(users.map(user => [user.id, user]));

const ages = Object.fromEntries(users.map(user => [user.name, user.age]));

const query = Object.fromEntries(pairs);

A reduce that starts from an object with properties, or that adds more than one property per step, isn't reported:

example.jsNo problems
const settings = flags.reduce((result, flag) => ({ ...result, [flag]: true }), { debug: false });

const index = users.reduce((result, user) => ({ ...result, [user.id]: user, [user.email]: user }), {});

Options#

OptionDefaultWhat it does
functions["_.fromPairs", "lodash.fromPairs"]Functions to report when they're called with one argument. A name can have dots, like "utils.toObject". Your list replaces the default.
example.jswith { "functions": ["utils.toObject"] }1 problem
const query = utils.toObject(pairs);

_.fromPairs isn't in the list anymore:

example.jswith { "functions": ["utils.toObject"] }No problems
const query = _.fromPairs(pairs);