4

I have a reduce function like below:

let el = scopes.reduce ((tot, {actions}) => tot + actions.length, 0);

I tried to transform it like this, but it seems that it is not the correct way:

let el = scopes.reduce ((tot, {actions.length: len}) => tot + len, 0);

Is there a way to do this or it is not possible.

Sohail Ashraf
  • 10,078
  • 2
  • 26
  • 42
Paul
  • 3,644
  • 9
  • 47
  • 113

1 Answers1

6

You were close, but you use nesting rather than dot notation:

// Outer −−−−−−−−−−−−−−−−−−−−v−−−−−−−−−−−−−−−−−−−−−−v
let el = scopes.reduce((tot, {actions: {length: len}}) => tot + len, 0);
// Inner −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^−−−−−−−−−−−−^

Live Example:

const scopes = [
    {actions: [1, 2, 3]},
    {actions: []},
    {actions: [4, 5]}
];
let el = scopes.reduce((tot, {actions: {length: len}}) => tot + len, 0);
console.log(el); // 5

The key thing to remember with destructuring is that the syntax is identical to object and array literals, complete with nesting; it's just that the information flow is the other direction. In an object literal, for instance, the data flows right to left, from the source (source) to the target (prop):

let source = 42;
let obj = {prop: source};
//           <−−−−−*

in destructuring, the data flows left to right, from the source (prop) to the target (target):

let {prop: target};
//     *−−−−−>
console.log(target); // 42

and the target can be a variable, an object property, or even another destructuring pattern. That's what we're using above: The target of the actions property is the destructuring pattern {length: len}, which puts the value of length into the variable len. Here's Figure 7-1 from my new book (see my profile for links):

Figure 7-1 from JavaScript: The New Toys


You could also use shorthand notation and use length in your callback:

let el = scopes.reduce((tot, {actions: {length}}) => tot + length, 0);

Live Example:

const scopes = [
    {actions: [1, 2, 3]},
    {actions: []},
    {actions: [4, 5]}
];
let el = scopes.reduce((tot, {actions: {length}}) => tot + length, 0);
console.log(el); // 5
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • initial value `0` is not required though. – AZ_ Jan 23 '20 at 09:46
  • @AZ_ - It is, for two reasons: 1. The values from the array are not simple values, they're objects we're extracting information from. 2. We don't know that the array isn't empty (`reduce` will throw on an empty array if there's no seed value). – T.J. Crowder Jan 23 '20 at 09:48
  • ahh ok I get it, for the first element it won't get the length. – AZ_ Jan 23 '20 at 09:54