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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.