Search code examples
javascriptarraysconcatenationreduce

does the curly braces change the reading of this function


I was writing a function to flatten an array from eloquent javascript using the concat and reduce methods. When i write my code like this:

    function flatten(args){
       return args.reduce((current,i) =>{
           current.concat(i);
       },[] );
   }

   let arrays = [[1, 2, 3], [4, 5], [6]];
   console.log(flatten(arrays));

i get the following error:

current.concat(i);
                ^

TypeError: Cannot read property 'concat' of undefined

but when i get rid of the curly braces '{}' in this section:

before:

return args.reduce((current,i) =>{
        current.concat(i);
    },[] );

after:

return args.reduce((current,i) =>
        current.concat(i)
    ,[] );
}

it prints out just fine. This format works fine when finding a sum with an initialization of 0. does the concat method not recognize the [] when it is within the curly braces '{}'.


Solution

  • Short answer: yes it is different. Your reducer needs to return a value in the function. The value of the current parameter is equal to the last return from the invocation of the last reduce function call. In the first invocation, the current parameter is equal to the initial value specified in the second parameter to the reduce function call (i.e. []).

    Explicitly returning current with the braced version would fix the issue as well:

    function flatten(args) {
       return args.reduce((current, i) => {
           return current.concat(i);
       }, []);
    }
    

    Without the curly braces, the return is implicitly returning the value returned by the concat expression, which is a new array.

    For more information on how arrow functions work, check out MDN's Arrow functions article. Specifically, this section talks about how it's implied:

    (param1, param2, …, paramN) => expression
    // equivalent to: => { return expression; }
    

    As well as this section:

    // When the only statement in an arrow function is `return`, we can remove `return` and remove
    // the surrounding curly brackets
    elements.map(element => element.length); // [8, 6, 7, 9]