Skip to content Skip to sidebar Skip to footer

Is Possible To Reduce The Complexity And Spaghetti Quality Of This Javascript Algorithm Solution?

Problem: Create a function that sums two arguments together. If only one argument is provided, then return a function that expects one argument and returns the sum. For example, ad

Solution 1:

functionaddTogether(a, b) {
  if (typeof a == "number") {
    if (arguments.length == 1) {
      returnb =>addTogether(a, b);
    } elseif (typeof b == "number") {
      return a + b;
    } 
  }
}

// as per OP's code// returns 3console.log("addTogether(1, 2) = " + addTogether(1, 2));
console.log("addTogether(1, 2, 3) = " + addTogether(1, 2, 3));
console.log("addTogether(1)(2) = " + addTogether(1)(2));
console.log("addTogether(1)(2, 3) = " + addTogether(1)(2, 3));
console.log("addTogether(1, 2, '3') = " + addTogether(1, 2, '3'));
console.log("addTogether(1)(2, '3') = " + addTogether(1)(2, '3'));
console.log("addTogether(1, 2, [3]) = " + addTogether(1, 2, [3]));
console.log("addTogether(1)(2, [3]) = " + addTogether(1)(2, [3]));
console.log("addTogether(1, 2, NaN) = " + addTogether(1, 2, NaN));
console.log("addTogether(1)(2, NaN) = " + addTogether(1)(2, NaN));
// returns NaNconsole.log("addTogether(1, NaN) = " + addTogether(1, NaN));
console.log("addTogether(1)(NaN) = " + addTogether(1)(NaN));
// returns undefinedconsole.log("addTogether() = " + addTogether());
console.log("addTogether(1)() = " + addTogether(1)());
console.log("addTogether('1') = " + addTogether('1'));
console.log("addTogether(1, '2') = " + addTogether(1, '2'));
console.log("addTogether(1)('2') = " + addTogether(1)('2'));
console.log("addTogether(1, [2]) = " + addTogether(1, [2]));
console.log("addTogether(1)([2]) = " + addTogether(1)([2]));

The following improvements have been suggested, but they would change the semantics of OPs code:

  • return undefined if a or b is NaN, as NaN is not a 'valid number'
  • return undefined if more than two arguments are provided instead of silently dropping them (thanks @PatrickRoberts)

If you don't mind returning a function for e. g. addTogether('x'), use:

functionaddTogether(a, b) {
  if (arguments.length == 1) {
    returnb =>addTogether(a, b);
  } elseif (typeof a == "number" && typeof b == "number") {
    return a + b;
  }
}

This way, your will always return a function for one argument and Number or undefined for two or more arguments = more robust code.

For ES5 compatibility and if you don't mind addTogether(2)() returning a function, replace b => addTogether(a, b) with addTogether.bind(undefined, a) (thanks @PatrickRoberts).

Solution 2:

You can use spread operator for improving your function and some Array functions like some or reduce :

In that way addTogether can accept more than one argument. If addTogether is called with one argument, the function returned can be called with more than one arguments too.

letisNotNumber = number=> typeof number != 'number';

let addTogether = function(...numbers){
  if(!numbers.length) return;
  if(numbers.length == 1){
    if(isNotNumber(numbers[0])) return;
    returnfunction(...otherNumbers){
      if(otherNumbers.some(isNotNumber)) return;
      return otherNumbers.reduce((prev, curr)=> prev + curr, numbers[0]);
    }
  } else {
    if(numbers.some(isNotNumber)) return;
    return numbers.reduce((prev, curr)=> prev + curr);
  }
}

// Will return a valueconsole.log(addTogether(1,2,3));
console.log(addTogether(1)(2,3));

// Will return undefinedconsole.log(addTogether(1, [2]));
console.log(addTogether(1)('2'));
console.log(addTogether(1)([2]));
console.log(addTogether());

Solution 3:

According to jscomplexity.org, OP's function has a cyclomatic complexity of 8 while the solution below have a cyclomatic complexity of 5 (based on the Babel ES5 transpilation).

This solution is functionally equivalent to OP's code, see tests below:

'use strict';

functionaddTogether(...augends) {
  if (augends.slice(0, 2).every(value =>typeof value === 'number')) {
    switch (augends.length) {
    case0:
      return;
    case1:
      return(addend) =>addTogether(augends[0], addend);
    default:
      return augends[0] + augends[1];
    }
  }
}

// should work (returns 3)console.log("addTogether(1, 2) = " + addTogether(1, 2));
console.log("addTogether(1, 2, 3) = " + addTogether(1, 2, 3));
console.log("addTogether(1)(2) = " + addTogether(1)(2));
console.log("addTogether(1)(2, 3) = " + addTogether(1)(2, 3));
console.log("addTogether(1, 2, '3') = " + addTogether(1, 2, '3'));
console.log("addTogether(1)(2, '3') = " + addTogether(1)(2, '3'));
console.log("addTogether(1, 2, [3]) = " + addTogether(1, 2, [3]));
console.log("addTogether(1)(2, [3]) = " + addTogether(1)(2, [3]));
console.log("addTogether(1, 2, NaN) = " + addTogether(1, 2, NaN));
console.log("addTogether(1)(2, NaN) = " + addTogether(1)(2, NaN));
// should return NaN (not sure if this "works" or not)console.log("addTogether(1, NaN) = " + addTogether(1, NaN));
console.log("addTogether(1)(NaN) = " + addTogether(1)(NaN));
// should not work (returns undefined)console.log("addTogether() = " + addTogether());
console.log("addTogether(1)() = " + addTogether(1)());
console.log("addTogether('1') = " + addTogether('1'));
console.log("addTogether(1, '2') = " + addTogether(1, '2'));
console.log("addTogether(1)('2') = " + addTogether(1)('2'));
console.log("addTogether(1, [2]) = " + addTogether(1, [2]));
console.log("addTogether(1)([2]) = " + addTogether(1)([2]));

For reference, here is my other solution which prohibits extraneous arguments and also tests against literal NaN values (which ironically are typeof "number"). Edit Unfortunately due to fixing the implementation for the test case console.log("addTogether(1)() = " + addTogether(1)());, it now has a cyclomatic complexity of 7:

'use strict';

functionaddTogether(...augends) {
  if (augends.every(value =>typeof value === 'number' && !isNaN(value))) {
    switch (augends.length) {
    case1:
      return(addend, ...addends) =>addTogether(augends[0], addend, ...addends);
    case2:
      return augends[0] + augends[1];
    }
  }
}

// should work (returns 3)console.log("addTogether(1, 2) = " + addTogether(1, 2));
console.log("addTogether(1)(2) = " + addTogether(1)(2));
// should not work (returns undefined)console.log("addTogether() = " + addTogether());
console.log("addTogether(1)() = " + addTogether(1)());
console.log("addTogether('1') = " + addTogether('1'));
console.log("addTogether(1, 2, 3) = " + addTogether(1, 2, 3));
console.log("addTogether(1, '2') = " + addTogether(1, '2'));
console.log("addTogether(1)('2') = " + addTogether(1)('2'));
console.log("addTogether(1, [2]) = " + addTogether(1, [2]));
console.log("addTogether(1)([2]) = " + addTogether(1)([2]));
console.log("addTogether(1)(2, 3) = " + addTogether(1)(2, 3));
console.log("addTogether(1, 2, '3') = " + addTogether(1, 2, '3'));
console.log("addTogether(1)(2, '3') = " + addTogether(1)(2, '3'));
console.log("addTogether(1, 2, [3]) = " + addTogether(1, 2, [3]));
console.log("addTogether(1)(2, [3]) = " + addTogether(1)(2, [3]));
console.log("addTogether(1, 2, NaN) = " + addTogether(1, 2, NaN));
console.log("addTogether(1)(2, NaN) = " + addTogether(1)(2, NaN));
console.log("addTogether(1, NaN) = " + addTogether(1, NaN));
console.log("addTogether(1)(NaN) = " + addTogether(1)(NaN));

Solution 4:

Why you don't provide arguments to function. I think that this is the simplest vay:

functionadd(arg1, arg2) {

    if (isNan(arg1) || isNan(arg2)) returnundefined;

    if (!arg2) {
        returnfunctionName(arg1);
    }

    return arg1 + arg2;
}

Solution 5:

You should read about function currying, bind, call, and apply. Currying is applicable to ES6, but bind,call and apply run everywhere.

Details on the MDN site https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind

In short, the solution you are looking for is:

functionaddTogether(a,b) {
    return a+b;
}
console.log(typeof addTogether); //-->functionconsole.log(typeof addTogether.bind(null,2)); //-->functionconsole.log(addTogether.bind(null,2)(3));//5console.log(addTogether(2,3)); //-->5

Yeah, it IS that simple, not kidding!

Post a Comment for "Is Possible To Reduce The Complexity And Spaghetti Quality Of This Javascript Algorithm Solution?"