2

I'm writing a sum(...numbers) function which takes in a bunch of arguments via the Spread operator and adds them. I want to pass an array of values to this function via the returnsAnArray() method, as shown below

function sum(...numbers) { let sum = 0; for (i = 0; i < numbers.length; i++) { sum += numbers[i]; } return sum; } function returnsAnArray() { return [1,2,3,4]; } console.log(sum(returnsAnArray()));

This outputs 01,2,3,4 on the console.

From what I understand the ... operator collects all the arguments passed to it and makes them available as an array. If the argument is a singular array then it the array is provided as is. But this does not behave that way.

Any ideas on how I can properly use loops here to get this working as expected?

3
  • To explain the code that you have in place, the ...numbers in the function sum means, there is no defined number of arguments, instead accept as many as passed. Now you are calling the function sum with a single argument of type array, so this is interpreted as the first parameter to the function sum to be of type array and not what you expect/intend. Hope the answer below helps Commented Jun 16, 2018 at 21:06
  • 1
    "the argument is a singular array then it the array is provided as is" - what made you think that? Commented Jun 16, 2018 at 21:06
  • The name for that ... construct is the rest parameter syntax. The spread syntax looks the same, but is different. Commented Apr 27, 2023 at 16:26

5 Answers 5

5

A spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments for functional calls are expected. Here is the MDN link

What the above means is that if you have a function that looks like the following

 function sum(x, y, z) { return x + y + z; } 

so the above function accepts three arguments, now when you pass in an array of length 3 using the spread operator, it replaces the values x, y, z with numbers[0], numbers1, numbers[2] respectively.

So you would be calling the above function such as

console.log(sum(...numbers));

function sum(x, y, z) { return x + y + z; } const numbers = [10, 12, 13]; console.log(sum(...numbers)); //output = 35

As mentioned in the comment to explain the code that you have in place, the ...numbers in the function sum means, there is no defined number of arguments, instead accept as many as passed. Now you are calling the function sum with a single argument of type array, so this is interpreted as the first parameter to the function sum to be of type array and not what you expect/intend.

Now In order to fix or achieve what you intend to do you got to spread the array that you are passing in as argument along the lines of

function sum(...numbers) { let sum = 0; for (i = 0; i < numbers.length; i++) { sum += numbers[i]; } return sum; } function returnsAnArray() { return [1,2,3,4]; } console.log(sum(...returnsAnArray()));

Sign up to request clarification or add additional context in comments.

Comments

3

If the argument is a singular array then it the array is provided as is.

No, you will get an array with an array. You have to spread the array to get what you expect:

 sum(...returnsAnArray()) 

Comments

3

What the ... operator does when used in a function's signature is allow for a dynamic number of arguments, and wraps all the given arguments in an array, somewhat similar to what arguments is, this, however, is usable in arrow functions and it is more readable and that arguments is an array-like object :

function fn(...args){ console.log(args); console.log(arguments); } fn(1,2,3,4); fn('s',2,'3'); fn([1,2,3], [1,2,3]);

So, as you might have noticed in the previous snippet when you pass arrays as arguments to a function that is using ... they become part of the array, not the array itself.

Therefore, for your specific case, there is no need for the use of ... as proven by the snippet below.

function sum(numbers) { console.log(numbers); console.log(arguments); let sum = 0; for (i = 0; i < numbers.length; i++) { sum += numbers[i]; } return sum; } function sumWithDynamicArgs(...numbers) { console.log(numbers); console.log(arguments); let sum = 0; for (i = 0; i < numbers.length; i++) { sum += numbers[i]; } return sum; } function returnsAnArray() { return [1, 2, 3, 4]; } console.log(sum(returnsAnArray())); console.log(sumWithDynamicArgs(...returnsAnArray()));

Comments

3

From what I understand the ... operator collects all the arguments passed to it and makes them available as an array.

I believe you are confusing spread with rest operator.

Rest wraps the rest of the arguments sent to a function in an array, which is exactly how you used it in your snippet.

I made use of your snippet to use spread to pass the arguments to sum function, which is exactly like: sum(1, 2, 3, 4) (console.log line).

Now, the sum function makes use of rest and takes all the values passed and wraps it in an array called numbers.

function sum(...numbers) { let sum = 0; for (i = 0; i < numbers.length; i++) { sum += numbers[i]; } return sum; } let numbers = [1,2,3,4] console.log(sum(...numbers));

Comments

0

If the sum function is intended to receive one array of numbers each time, you should just get rid of the spread operator.

If you want the function to accept several arrays, then try something like this:

function sum(...args) { let sum = 0; for (let i = 0; i < args.length; i++) { for (let j = 0; j < args[i].length; j++) { sum += args[i][j]; } } return sum; } console.log(sum([0, 1, 2, 3]));

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.