1

if I have:

function foo(number, ...args) {
   //foo to add args to sum
}

and I want a caller to be able to call foo like:

foo(10, 1, 2, 3); // 16

or:

foo(10, [1, 2, 3]); //16

The question is how to implement this. Can I do this:

function foo(number, ...args) {
    let toAddArr = Array.isArray(args[0]) ? args[0] : args;
    for (let toAdd of toAddArr) {
        number = number + toAdd;
    }
    return number;
}
4
  • do you always want only add the numbers? Commented Oct 23, 2015 at 15:44
  • That looks fine. Did you try it? Commented Oct 23, 2015 at 15:44
  • @webduvet just an example, I am writing an entirely different function in which args can be arguments or an array Commented Oct 23, 2015 at 15:46
  • @RocketHazmat Not yet... Commented Oct 23, 2015 at 15:46

4 Answers 4

5

You could use some recursion:

function foo(...args) {
    var sum = 0;
    args.forEach((arg) => {
        if (!Array.isArray(arg))
            sum += arg
        else
            sum += foo(...arg); // if it's an array, destructure
    });
    return sum;
}

With that code, you can even pass arrays inside arrays inside arrays if you want :)

Edit, with a for loop:

function foo(...args) {
    var sum = 0;
    for (var arg of args) {
        if (!Array.isArray(arg))
            sum += arg
        else
            sum += foo(...arg); // if it's an array, destructure
    };
    return sum;
}
Sign up to request clarification or add additional context in comments.

2 Comments

I dont understand the (arg) => {} syntax, I mean I know it is an arrow function but I don't understand how you are using it.
It's just the forEach function of Array, I prefer to use that instead of a for loop but it does the same thing. I added a for version so you can the difference, not much.
1

Well you can convert the arguments to an array and concat them.

function foo(){
   return [].concat.apply([],Array.prototype.slice.call(arguments)).reduce( function (p,c) { return p + c; }, 0);
}
var x1 = foo(10, [1,2,3]);
console.log(x1);

var x2 = foo(10,1,2,3);
console.log(x2);

3 Comments

You can use [].slice.call(arguments) instead of Array.prototype.slice.call(arguments)
How does the Array.prototype.slice(arguments) work if arguments = 10, [1, 2, 3]? Isn't call expecting arguments instead of array?
arguments is not an array so it converts it to an array so I can run array methods against it. The concat line than collapses the array (if there is one).
1

You can use .concat with .apply, and for sum .reduce, like this

function foo(...args) {
  return ([].concat.apply([], args)).reduce(function (prev, curr) {
    return prev + curr;
  }, 0);
}

Example

Comments

0

for nested arrays recursion might work nicely. You can have only numbers or arrays or nested arrays or mixed.

  function add() {
    return Array.prototype.reduce.call(arguments, function(p, c) {
      if (Array.isArray(c)) {
        return p + add.apply(null, c);
      } else {
        return p + c;
      }
    });
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.