# Arguments Optional

## Problem Explanation

It can be quite complicated to understand what needs to be done. There are always many ways to do something when coding but regardless of the algorithm used, we have to create a program that does the following:

• It has to add two numbers passed as parameters and return the sum.
• It has to check if any of the numbers are actual numbers, otherwise return undefined and stop the program right there.
• It has to check if it has one or two arguments passed. More are ignored.
• If it has only one argument then it has to return a function that uses that number and expects another one, to then add it.

## Hints

### Hint 1

Every time you deal with an argument, you have to check if it is defined and if it is a number.

### Hint 2

When working on the case that it needs to return a function, using closure can help you write the new function in terms of `addTogether()`.

### Hint 3

The early return pattern can simplify your code.

## Solutions

Solution 1 (Click to Show/Hide)
``````function addTogether() {
const [first, second] = arguments;

if (typeof (first) === "number") {
if (typeof (second) === "number") return first + second;
if (arguments.length === 1) return (second) => addTogether(first, second);
}
}
``````
Solution 2 (Click to Show/Hide)
``````function addTogether() {
const [first, second] = arguments;
// First argument is not a number
if (typeof(first) !== "number") {
return undefined;
}
// First argument is a number
//  and second argument is not defined
else if (arguments.length === 1) {
// New argument is not a number
if (typeof(second) !== "number") {
return undefined;
}
// New argument is a number
else {
return first + second;
}
}
// Note: returning a *function*
}
// First argument is a number
//  and second argument is not a number
else if (typeof(second) !== "number") {
return undefined;
}
// First argument is a number
//  and second argument is a number
else {
return first + second;
}
}
``````
Solution 3 (Click to Show/Hide)
``````function addTogether() {
const [first, second] = arguments;

if (typeof (second) === "number") return first + second;
}

if (typeof (first) === "number") {
if (arguments.length === 1) return addSecond;
if (arguments.length === 2) return addSecond(second);
}
}
``````
84 Likes

This is my solution. It is shorter but not sure if it is as robust as the āofficialā solutions. (I donāt see the need to use the āargumentsā object.)

``````function addTogether(a, b) {
// only if valid number provided
if (Number.isFinite(a)) {
if (!b) {
return function(c) {
if (Number.isFinite(c)) {
return a + c;
}
};
}
else if (Number.isFinite(b)) {
return a + b;
}
}
// returns undefined by default
}

``````
34 Likes

Cleanest āBasic Code Solutionā I came up with so far (using the arguments object):

``````function addTogether() {
//Variable and subroutine declaration (optional, but makes code cleaner)
var args = arguments;
var a = args[0];
var b = args[1];
function isNum(num) {
return Number.isInteger(num);
}

//Actual program: relies on implicit return of 'undefined'
//Note: while refactoring I remove curly braces if not required
if (isNum(a)) {
if (isNum(b))
return a + b;
else if (!b)
return function(b) {
if (isNum(b))
return a + b;
};
}
}
``````
35 Likes

In all of the examples, if you test something where you have one argument that is not a number, such as `addTogether("string")(3);` it always results in `TypeError: addTogether(...) is not a function`.

Why is this happening? And is there a way to avoid it?

4 Likes

Looks like this has been covered already, no surprise there

``````
var len = arguments.length;
var a = arguments[0];
var b = arguments[1];
var isNum = function(arg) { return Number.isFinite(arg); };
if (len === 1 && isNum(a)) {
return function(x) {
if (isNum(x)) {
return a + x;
}
};
}
else if (len === 2 && isNum(a) && isNum(b)) {
return a + b;
}
}

``````
8 Likes

Iāve edited the basic solution to include more than 2 inputs with a loop.

``````function addTogether() {
var checkNum = function(num) {
if (typeof num !== 'number') {
return undefined;
} else {
return num;
}
};
var total = 0;
if (arguments.length > 1) {

for (var i = 0; i < arguments.length; i++) {
var a = checkNum(arguments[i]);
var b = checkNum(arguments[i + 1]);
if (a === undefined || b === undefined) {
return undefined;
} else {
total = arguments[i] + arguments[i +1];
}
}

} else {
var oneArg = arguments[0];
if (checkNum(oneArg)) {
return function(arg2) {
if (oneArg === undefined ||
checkNum(arg2) === undefined) {
return undefined;

} else {
return oneArg + arg2;
}
};
}
}

}

1 Like

I approached the problem a little differently. Iām not sure if itās as elegant, but it works! Thoughts?

``````
var args = [].slice.call(arguments);
if (arguments.length > 1 && args.filter(function(x){return typeof x === "number";}).length === 2) {
return arguments[0] + arguments[1];
} else if (arguments.length === 1 && typeof arguments[0] === "number") {
var prev = arguments[0];
return function(num) {
if (typeof num === "number")
return prev + num;
};
}
}

``````
4 Likes

a short-liner solution:

``````function addTogether() {
'useversion: 6';
if (arguments.length > 1 && Array.from(arguments).every(item => typeof item === "number") ) {
return Array.from(arguments).reduce((acc, val) => acc + val);
}
if (arguments.length === 1 && typeof arguments[0] === "number") {
}
}

2 Likes

My recursive solution!

``````function addTogether() {
const [a, b] = arguments;

if (typeof a !== 'number' || (b && typeof b !== 'number')) {
return undefined;
}

if (b) {
return a + b;
}

}``````
41 Likes
``````> function addTogether() {

return function(y) {

if (typeof x !== 'number' || typeof y !== 'number') {
return undefined;
}

return x + y;
};
}

if (typeof arguments[0] !== 'number') {
return undefined;
}else
if (arguments.length > 1) {
}else
}

One test case fails for my code. Kindly let me know why?
It returns āundefinedā (which is expected output), still the case fails.

if (typeof(x) !== ānumberā)
return undefined;
var args = Array.from(arguments);

if(args.length > 1)
{
if (typeof args[1] !== ānumberā)
return undefined;
else
return x + args[1];
}
else
return function(y){
return x+y;
};
}

1 Like
``````function addTogether() {
let params = [].slice.call(arguments);

if(!params.every(param => typeof param === 'number')) {
return undefined
}

if(params.length > 1) {
return params.reduce((acc, cur) => acc + cur)
} else {
let firstParam = arguments[0],
};
}

return params
}

3 Likes
``````
var a = Array.from(arguments);
function nan(n){
return typeof n != 'number';
}
return (a.length == 2) ?
(nan(a[0]) || nan(a[1])) ? undefined : a[1] + a[0]
:(nan(a[0])) ? undefined : (function(n){ return (nan(n)) ? undefined : n+a[0];});
}

``````

Can someone please explain this to me? I cannot wrap my head around how to access the second argument if there is only one passed to the function. For example, in the callback addTogether(2)(3) how would I access the (3)? Arguments[1] does not do it cause itās not a second argument. Any help would be appreciated.

10 Likes

@TeeJay letās break the function call

``````addTogether(2)(3) is equivalent to below
fr(3)
``````

You can access the second argument (i.e 3) in the function you return when only one argument (i.e. 2) is passed to addTogether.

3 Likes

@sh4hidkh4n I still donāt understand but thank you for trying to explain. I will continue to look trough different solutions to try to understand. Are the any resources that I could read to learn more about this particular concept?

4 Likes

Check about how functions are used like variables : http://ryanchristiani.com/functions-as-first-class-citizens-in-javascript/ and anonymous functions http://helephant.com/2008/08/23/javascript-anonymous-functions/

1 Like

Help! Not qualifying for the last test case, even though it returns `undefined`. Can pls anyone tell me whatās wrong.

``````function addTogether() {

var args = [].slice.call(arguments);
var und;
//console.log(args);

if(args.length > 1) {
var sum = 0 ;

for(var i in args) {
if( typeof args[i] === 'number' ) {
sum += args[i];
} else {
return und;
}
}
return sum;
} else {

if( typeof args[0] === 'number' ) {
//console.log(args[0] + "here");
return function(n){
if(typeof n === 'number') {
return n + args[0];
} else {
return typeof undeclared;
}
};
}
}
return und;
}