Creating a function with variable number of inputs?
Use fprintf
with varargin
for this:
f = @(varargin) fprintf('var%i= %i\n', [(1:numel(varargin));[varargin{:}]])
f(5,6,7,88)
var1= 5
var2= 6
var3= 7
var4= 88
The format I've used is: 'var%i= %i\n'
. This means it will first write var
then %i
says it should input an integer. Thereafter it should write =
followed by a new number: %i
and a newline \n
.
It will choose the integer in odd positions for var%i
and integers in the even positions for the actual number. Since the linear index in MATLAB goes column for column we place the vector [1 2 3 4 5 ...]
on top, and the content of the variable in the second row.
By the way: If you actually want it on the format you specified in the question, skip the \n
:
f = @(varargin) fprintf('var%i= %i', [(1:numel(varargin));[varargin{:}]])
f(6,12,3,15,5553)
var1= 6var2= 12var3= 3var4= 15var5= 5553
Also, you can change the second %i
to floats (%f
), doubles (%d
) etc.
If you want to use actual variable names var1, var2, var3, ...
in your input then I can only say one thing: Don't! It's a horrible idea. Use cells, structs, or anything else than numbered variable names.
Just to be crytsal clear: Don't use the output from this in MATLAB in combination with eval
! eval
is evil. The Mathworks actually warns you about this in the official documentation!
Function call with variable number of input arguments when number of input arguments is not explicitly known
Couple of helpful points to construct a solution:
- This post shows you how to construct a Cartesian product between arbitrary arrays using
ndgrid
. cellfun
accepts multiple cell arrays simultaneously, which you can use to index specific elements.- You can capture a variable number of arguments from a function using cell arrays, as shown here.
So let's get the inputs to ndgrid
from your outermost array:
grids = cellfun(@(x) 1:numel(x), pth, 'UniformOutput', false);
Now you can create an index that contains the product of the grids:
index = cell(1, numel(pth));
[index{:}] = ndgrid(grids{:});
You want to make all the grids into column vectors and concatenate them sideways. The rows of that matrix will represent the Cartesian indices to select the elements of pth
at each iteration:
index = cellfun(@(x) x(:), index, 'UniformOutput', false);
index = cat(2, index{:});
If you turn a row of index
into a cell array, you can run it in lockstep over pth
to select the correct elements and call mintersect
on the result.
for i = index'
indices = num2cell(i');
selection = cellfun(@(p, i) p{i}, pth, indices, 'UniformOutput', false);
mintersect(selection{:});
end
This is written under the assumption that pth
is a row array. If that is not the case, you can change the first line of the loop to indices = reshape(num2cell(i), size(pth));
for the general case, and simply indices = num2cell(i);
for the column case. The key is that the cell from of indices
must be the same shape as pth
to iterate over it in lockstep. It is already generated to have the same number of elements.
Functions with variable number of input parameters
Advanced features like VARIADIC
or even polymorphic input types and dynamic SQL are very powerful. The last chapter in this answer provides an advanced example:
- Refactor a PL/pgSQL function to return the output of various SELECT queries
But for a simple case like yours, you can just use default values for function parameters. It all depends on exact requirements.
If the columns in question are all defined NOT NULL
, this would probably be simpler and faster:
CREATE OR REPLACE FUNCTION update_site(_name text -- always required
, _city text DEFAULT NULL
, _telephone integer DEFAULT NULL)
RETURNS integer AS
$func$
BEGIN
IF _city IS NULL AND _telephone IS NULL THEN
RAISE WARNING 'At least one value to update required!';
RETURN; -- nothing to update
END IF;
UPDATE "Sites"
SET "City" = COALESCE(_city, "City")
, "Telephone" = COALESCE(_telephone, "Telephone")
WHERE "SiteName" = _name;
END
$func$ LANGUAGE plpgsql;
Read about default values in the manual!
To avoid naming conflicts between parameters and column names I make it a habit to prefix input parameters with _
. That's a matter of taste and style.
- The first parameter
name
has no default, since it is required at all times. - Other parameters can be omitted.
- At least one is required, or a
WARNING
is raised and nothing else happens. - The
UPDATE
will only change columns for given parameters. - Can easily be expanded for N parameters.
Function call
Since Postgres 9.5:
The simple way is with positional notation for parameters. This only allows to omit the rightmost parameter(s):
SELECT update_site('foo', 'New York'); -- no telephone
Named notation allows to omit any parameter that has a default value:
SELECT update_site(name => 'foo', _telephone => 123); -- no city
Both can be combined in mixed notation:
SELECT update_site('foo', _telephone => 123); -- still no city
In Postgres 9.4 or older, :=
was used for assignment in the call:
SELECT update_site(name := 'foo', _telephone := 123);
SELECT update_site('foo', _telephone := 123);
Still valid in Postgres 12 for backward compatibility, but rather use the modern notation.
Can a variable number of arguments be passed to a function?
Yes. You can use *args
as a non-keyword argument. You will then be able to pass any number of arguments.
def manyArgs(*arg):
print "I was called with", len(arg), "arguments:", arg
>>> manyArgs(1)
I was called with 1 arguments: (1,)
>>> manyArgs(1, 2, 3)
I was called with 3 arguments: (1, 2, 3)
As you can see, Python will unpack the arguments as a single tuple with all the arguments.
For keyword arguments you need to accept those as a separate actual argument, as shown in Skurmedel's answer.
How do i make a function with a variable number of parameters?
First of all Variadic arguments from C
are considered a bad practice in C++ and should be avoided.
There are plenty of better C++ solutions which are able to replace this C feature.
Old fashioned std::vector
:
std::vector<int> filterPrimes(std::vector<int> a) {
auto end = std::remove_if(a.begin(), a.end(), [](auto x) {
return !isPrime(x)
};
a.remove(end, a.end());
return a;
}
Or std::initializer_list
std::vector<int> filterPrimes(std::initializer_list<int> l) {
std::vector<int> r;
std::copy_if(l.begin(), l.end(), std::back_inserter(r), isPrime);
return r;
}
Or Variadic templates, or template with iterator ranges, or ... .
Function with a variable number of parameters
I think this answers your question.
def _more_data_(*args):
f = open(file,'w')
f.write(str(args[0])+';\n')
return
Or you can do this to write every argument you pass.
def _more_data_(*args):
f = open(file,'w')
for i in range(len(args)):
f.write(args[i])
return
Happy to help : )
Creating a function in R with variable number of arguments,
d <- function(...){
x <- list(...) # THIS WILL BE A LIST STORING EVERYTHING:
sum(...) # Example of inbuilt function
}
d(1,2,3,4,5)
[1] 15
C++ Function with variable number and types of arguments as argument of another function
It is not foolproof, but any possible errors will be caught at compile time (ie. the code will not compile). It should work file, as long as the provided parameters match those of the called function, and a matching <<
operator exists for each parameter.
template<class Fn, class...Args>
void execute_and_print(Fn fn, Args...args) {
int f[sizeof...(Args)] = { (std::cout << args << ", ", 0)... };
fn(args...);
}
Refer to https://en.cppreference.com/w/cpp/language/parameter_pack. The sizeof...
command is actually the number of elements, not their combined size.
Function with variable number of arguments
Yes you can write something like this:
void PrintReport(string header, params int[] numbers)
{
Console.WriteLine(header);
foreach (int number in numbers)
Console.WriteLine(number);
}
Variable number of arguments in C++?
You probably shouldn't, and you can probably do what you want to do in a safer and simpler way. Technically to use variable number of arguments in C you include stdarg.h. From that you'll get the va_list
type as well as three functions that operate on it called va_start()
, va_arg()
and va_end()
.
#include<stdarg.h>
int maxof(int n_args, ...)
{
va_list ap;
va_start(ap, n_args);
int max = va_arg(ap, int);
for(int i = 2; i <= n_args; i++) {
int a = va_arg(ap, int);
if(a > max) max = a;
}
va_end(ap);
return max;
}
If you ask me, this is a mess. It looks bad, it's unsafe, and it's full of technical details that have nothing to do with what you're conceptually trying to achieve. Instead, consider using overloading or inheritance/polymorphism, builder pattern (as in operator<<()
in streams) or default arguments etc. These are all safer: the compiler gets to know more about what you're trying to do so there are more occasions it can stop you before you blow your leg off.
Related Topics
Rails Find Record with Zero Has_Many Records Associated
SQL Like Condition to Check for Integer
SQL Error: Ora-00942 Table or View Does Not Exist
Redundant Data in Update Statements
Finding a Top Level Parent in SQL
How to Measure the Execution Time of a Query on Spark
How to Transform Comma Separated Column into Multiples Rows in Db2
Differencebetween a Stored Procedure and a View
Convert a String to Int Using SQL Query
Select Rows with Same Id But Different Value in Another Column
Doesn't Linq to SQL Miss the Point? Aren't Orm-Mappers (Subsonic, etc.) Sub-Optimal Solutions
Copy Table Structure to New Table in SQLite3
Update Multiple Rows with One Query
How to Generate Ranks in MySQL
Combinations (Not Permutations) from Cross Join in SQL
Does Assigning Stored Procedure Input Parameters to Local Variables Help Optimize the Query