Mikhail Batcer
Mikhail Batcer

Reputation: 2065

Make function accept both variable number of arguments, or values in array

In JavaScript, it is pretty easy now to make a function accept a variable number of arguments:

function doSomething(...args) {
    args.forEach(arg => console.log(arg));
}

Now it can be called like doSomething(1, 2, 3) and all arguments will be available inside the function as array args. The output will be:

1
2
3

Now I want to call the function, passing all values in one array, like this:

const arr = [1, 2, 3];
doSomething(arr);

and have the same result. To do it, I have to use lodash's _.flatten inside the function:

doSomething(...args) {
    args = _.flatten(args);
    ...
}

Are there better ways to modify my function to do this?

I don't need any solution, I already have one. I need good solutions doing exactly what I need, but without third party libraries like Lodash and still elegant. I ask because of curiosity, not because I don't know how to do that at all :-)

Upvotes: 0

Views: 46

Answers (2)

Bergi
Bergi

Reputation: 664425

If you don't want to flatten all arrays but only use one, then the following should do:

if (Array.isArray(args[0])) args = args[0];

You might also want to check for args.length == 1 in that case.

But in general, instead of overloading your function to do different things with different numbers or types arguments, it's much easier and safer to provide multiple functions:

function doSomething(...args) {
    // implementation
}
function doSomethingArr(arr) {
    return doSomething(...arr);
}

or

function doSomething(...args) {
    return doSomethingArr(args);
}
function doSomethingArr(arr) {
    // implementation
}

Upvotes: 1

PeterMader
PeterMader

Reputation: 7285

Take a look at apply:

function doSomething (...args) {
  args.forEach(arg => console.log(arg));
}

const arr = [1, 2, 3];
doSomething.apply(null, arr);

Or check if the first argument is an array:

function doSomething () {
  let args;
  if (Array.isArray(arguments[0])) {
    args = arguments[0];
  } else {
    args = Array.slice(argument);
  }
  args.forEach(arg => console.log(arg));
}

const arr = [1, 2, 3];
doSomething.apply(null, arr);

This approach however is a bit more verbose and doesn't make use of the spread operator. Also, things like this would not work:

const arr = [[1, 2], [3, 4]];
doSomething.apply(null, arr);

Upvotes: 1

Related Questions