Arguments Optional advanced answer not understood

I wasn’t able to get this answer on my own, but the advanced answer was the closest to what I had written. I just don’t understand the last bit.

//jshint esversion: 6
    function addTogether() {
      var args = Array.from(arguments);
      return args.some(n => typeof n !== 'number') ? 
        undefined: 
        args.length > 1 ?
          args.reduce((acc, n) => acc += n, 0):
          (n) => typeof n === "number" ? 
            n + args[0]:
            undefined;
    }

    // test here
    addTogether(2,3);

Specifically, why do we have to restate the (n) => typeof n === "number" ? after reducing? Shouldn’t that already have been filtered out initially? This is what kept me from getting the answer on my own, and I still don’t understand it.

Following the logic of the whole mess, the return is a TRULY ugly mess. It works, yes. Here’s what it’s saying:

  • if there are NOT any numbers in the args array, return undefined (that’s the first n => typeof n !== 'number' line).
  • If there ARE, and there are NOT more than ONE argument (addTogether can’t add a single number), then return undefined.
  • If there ARE numbers, and there are MORE THAN one element in the args array, then reduce them by adding all elements together and return the resulting value.

That should handle all the cases. From what I’m seeing, the two lines toward the end:

(n) => typeof n === "number" ?
n+args[0]

…either checks for an existing GLOBAL n and checks if it contains a numeric value, then adds the first arg to THAT, or fails. Why? Durned. if I know. The rest makes perfect sense.

Let me say, though, MAD kudos for figuring out that logic on your own. That’s pretty deep stuff. I broke bits off my brain trying to read that stuff! :wink:

1 Like

The code should be called nested ternary, why not to use them.

I might be wrong here but i think it is doing currying (or partial application, im not to sure about functional stuff). If the addTogether function is only given one argument it returns a function which you can then run with the second argument.

const addAgain = addTogether(2);
addAgain(3)
returns 5
1 Like

Thanks for the help! I’m glad I’m not the only one whose brain cracked in half a bit :slight_smile:

1 Like

I will restate my point again, i will try to make it more clear this time. Again this is just my understanding of the code, if I’m wrong about this then i will happily accept any corrections.

The last typeof check is for the return function. If you only pass addTogether one argument it returns a function with a closure over the args[0] argument. When you run the captured return function it checks that the argument provided is a number, if it is not a number, it will return undefined, if it is a number, it will sum that argument with the closed over args[0] argument from the first run.

addTogether()
returns the function
(n) => typeof n === "number" ? 
  n + args[0]:
  undefined
  
const addSecondArg = addTogether(3)

addSecondArg(2)
returns 5

addSecondArg('not a number')
returns undefined

ahhhh okay! I’m just now beginning the You Don’t Know JS series’ book on Closures, so I don’t understand them yet. I understand all the words you said individually, but not put together quite yet :wink: I appreciate the explanation, and I’ll look at this again when I have a better understanding of closures. Thanks for the clarification!

You’re absolutely right, passing a single argument to the addTogether returns a function that will then add that to that single argument. Not sure if its a bug or not, but IMHO running addSecondArg() multiple times should accumulate.

Purely a nitpicky observation, and not germane to this conversation at all. I did test this one out as a jsFiddle, first passing two params, then passing eight, then passing four with one as a string, then passing one and using the returned function as you show. Pretty slick, really. Thanks for the explanation!