me-me
me-me

Reputation: 5809

Javascript reduce shorthand not returning object

Why would one work and the other not ?

const b = {
  age: 20,
  name: "John Doe"
}

const sortedB = Object.entries(b).sort().reduce((acc, [key, val]) => acc[key] = val,{});

Output: John Doe

The top is leaving out the block brackets which says return acc automatically . The bottom is saying use the block braces which means you have to manually return acc

  const sortedB = Object.entries(b).sort().reduce((acc, [key, val]) => {
    acc[key] = val;
    return acc;
  },{});

Output: {age: 20, name: "John Doe"}

Upvotes: 4

Views: 2838

Answers (3)

Ruslan Korkin
Ruslan Korkin

Reputation: 5081

You can use even short version with ES6:

Object.entries(b).sort().reduce((acc, [key, val]) => ({ ...acc, ...{ [key]: val } }),{});

Upvotes: 0

Estus Flask
Estus Flask

Reputation: 222369

As it's already explained in another answer, there's no way how acc[key] = val expression can return acc automatically, because it evaluates to val, not acc.

A recipe that can be conveniently used in reduce function in ES6 is Object.assign because it returns an object it extends:

Object.entries(b).sort().reduce((acc, [key, val]) => Object.assign(acc, { [key]: val }) ,{});

It's more costly than acc[key] = val; return acc but can be used in non-critical places (in performance-critical places Object.entries and reduce aren't welcome, too) and can be used with implied arrow return.

Upvotes: 2

Felix Kling
Felix Kling

Reputation: 816364

The top is leaving out the block brackets which says return acc automatically

No, that's not what it means. How/why should JavaScript know to return acc?

If you have an arrow function with only an expression as a body, then the result of that expression is returned. And the result of an assignment is the value that was assigned. Example:

var func = () => 1;
console.log(func()); // 1

func = x => x;
console.log(func(42)) // 42

func = (x, y) => y = 42;
console.log(func(1,2)); // 42

func = x => (x, 42);
console.log(func(21)); // 42

func = x => (42, x);
console.log(func(21)); // 21

If you want the value of acc returned then you have to make sure the expression evaluates to that value, e.g. with the comma operator:

 (acc, [key, val]) => (acc[key] = val, acc)
 //                    ^^^^^^^^^^^^^^^^^^^
 //  the comma operator returns the result of the right expression

Upvotes: 8

Related Questions