Variadic Functions in Javascript

Variadic functions are functions that can accept a variable number of arguments. They allow you to pass an arbitrary number of arguments to a function, and the function can handle them accordingly. The term “variadic” comes from the Latin word “varius,” meaning “various” or “varying.”

In JavaScript, functions are typically defined with a fixed number of parameters. However, variadic functions provide flexibility when you don’t know in advance how many arguments will be passed or when you want to handle a dynamic number of arguments.

To define a variadic function in JavaScript, you can use the arguments object or leverage the rest parameter syntax (...). The arguments object is an array-like object accessible within the body of a function, containing all the arguments passed to the function. The rest parameter syntax, introduced in ECMAScript 2015 (ES6), allows you to represent an indefinite number of arguments as an array.

variadic function using the arguments object:

function sum() {
  let total = 0;
  for (let i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }
  return total;
}
console.log(sum(1, 2, 3)); // Output: 6
console.log(sum(4, 5, 6, 7)); // Output: 22

In the above example, the sum() function can accept any number of arguments. It iterates over the arguments object and accumulates the values to calculate the sum.

Here’s the same example using the rest parameter syntax:

function sum(...numbers) {
  let total = 0;
  for (let i = 0; i < numbers.length; i++) {
    total += numbers[i];
  }
  return total;
}
console.log(sum(1, 2, 3)); // Output: 6
console.log(sum(4, 5, 6, 7)); // Output: 22

In this version, the sum() function uses the rest parameter ...numbers to collect all the passed arguments into an array called numbers.

Variadic functions are useful in scenarios where you want to perform operations on multiple values without having to define a fixed number of parameters. They provide flexibility and convenience when dealing with functions that need to handle a varying number of arguments.

Calling Variadic Function Inside Variadic Function:

To call a variadic function inside another variadic function, you can simply pass the arguments received by the outer function to the inner function. This can be achieved by using the spread operator (...) to spread the arguments into the inner function call. Also read difference between rest parameter and spread operator.

function multiply(...numbers) {
  return numbers.reduce((acc, curr) => acc * curr, 1);
}
function calculateProduct(...valueSets) {
  const products = valueSets.map((values) => multiply(...values));
  return multiply(...products);
}
console.log(calculateProduct([2, 3], [4, 5], [6, 7])); // Output 5040
//valueSets will be [[2, 3], [4, 5], [6, 7]]
//products will be [6, 20, 42]
 console.log(calculateProduct([[2, 3], [4, 5], [6, 7]]));// this has just one argument [[2, 3], [4, 5], [6, 7]]
//output NaN
// valueSets will be [ [ [ 2, 3 ], [ 4, 5 ], [ 6, 7 ] ] ]
// products will be [ NaN ]
// You need to flatten the array here to get the valid result.Modify the calculateProduct function to flatten the array.

In this example, the multiply() function is a variadic function that calculates the product of multiple numbers. The calculateProduct() function is also variadic and takes multiple sets of values. It calls the multiply() function for each set of values using the spread operator ... to expand the values into individual arguments.

When calling calculateProduct([2, 3], [4, 5], [6, 7]), it passes three sets of values ([2, 3], [4, 5], [6, 7]) to the multiply() function, which calculates the product of each set. Finally, the calculateProduct() function uses the spread operator again to pass the calculated products as arguments to another call to multiply(), resulting in the overall product.

   function concatenate(...strings) {
     return strings.join('');
   }
   function concatenateAll(...valueSets) {
     const strings = valueSets.flat(); // Flatten the array of arrays
     return concatenate(...strings);
   }
   console.log(concatenateAll('Hello', ' ', 'World', '!')); // Output: 'Hello World!'
   console.log(concatenateAll('This', ' ', 'is', ' ', 'cool.')); // Output: 'This is cool.'
   console.log(concatenateAll(['Hello'], [' ', 'World', '!']));// Output: 'Hello World!'

The concatenateAll function accumulates and flattens the string arguments provided to it, and then calls the concatenate function to perform the concatenation operation on the flattened array of strings. This allows you to concatenate strings regardless of whether they are passed as separate arguments or as arrays, providing flexibility in how the function is used..

Example:

function concatenate(...strings) {
  return strings.join('');
}
function concatenateAll(...valueSets) {
  const filteredValueSets = valueSets.map((values) => filterStrings(...values));
  return concatenate(...filteredValueSets);
}
function filterStrings(...strings) {
  // Filter out strings with less than 3 characters
  const filteredStrings = strings.filter((str) => str.length >= 3);
  // Perform any other filtering or preprocessing operations on the strings
  // ...
  return filteredStrings;
}
console.log(concatenateAll(['Hello'], [' ', 'World', '!'])); // Output: 'HelloWorld!'
console.log(concatenateAll(['This'], [' ', 'is'], [' ', 'cool.'])); // Output: 'Thiscool.'
console.log(concatenateAll(['I', 'am'], [' ', 'a', 'developer'], [' ', '!', '!', '!'])); // Output: 'developer'

In this example, the filterStrings function is added to demonstrate the filtering logic applied to the string sets before concatenation. The filtering logic in this case filters out strings with less than 3 characters using the filter method. You can modify the filtering logic according to your specific requirements.

The concatenateAll function calls filterStrings within the map method to filter each set of strings before performing the concatenation. It then calls the concatenate function to concatenate the filtered string sets.

   function sum(...numbers) {
     return numbers.reduce((acc, curr) => acc + curr, 0);
   }
   function calculateTotal(...valueSets) {
     const sums = valueSets.map((values) => sum(...values));
     return sum(...sums);
   }
   console.log(calculateTotal([1, 2, 3], [4, 5, 6], [7, 8, 9])); // Output: 45 (1+2+3+4+5+6+7+8+9)
   console.log(calculateTotal([10, 20], [30, 40], [50, 60])); // Output: 210 (10+20+30+40+50+60)

In this example, the sum function calculates the sum of a variable number of numeric arguments using the reduce method. The calculateTotal function is a variadic function that calls sum within it to calculate the sum of each values array obtained from multiple calls. By aggregating the sums using map and then calling sum on the aggregated sums, you can obtain the total sum across all the calls.

By using the calculateTotal function, you can avoid calling the sum function multiple times individually. Instead, you can pass multiple sets of numbers to calculateTotal, and it will internally handle the accumulation of sums from those sets.

This approach provides a more convenient and concise way to aggregate and process the values without the need for multiple function calls. It encapsulates the logic of accumulating sums within the calculateTotal function, making the code more readable and modular.

Calling a variadic function within another variadic function can provide flexibility in handling variable-length arguments and enable aggregation or accumulation of values from multiple function calls. The exact use case will depend on the specific requirements and desired behavior of your code.

Scroll to Top