How can I use a variable number of structure fields as function arguments?
14 views (last 30 days)
Show older comments
Hello,
I have a structure that conatins a function handle and any number of other variables (in this case 4), like so:
MyStruct = struct('MyFun',@example,'a',1,'b',2,'c',5,'d',37);
where example is a simple function that takes in a variable number of arguments and displays them, like so:
function [] = example(varargin)
for n = 1:2:length(varargin)
disp(['Argument ' varargin{n} ' = ' num2str(varargin{n+1})])
end
I would like to call the function handle (in this case @example) using the variables stored in MyStruct, like so:
>> X = fieldnames(MyStruct)
X =
5×1 cell array
{'MyFun'}
{'a' }
{'b' }
{'c' }
{'d' }
>> MyStruct.MyFun(X{2}, MyStruct.(X{2}), X{3}, MyStruct.(X{3}), X{4}, MyStruct.(X{4}), X{5}, MyStruct.(X{5}))
Argument a = 1
Argument b = 2
Argument c = 5
Argument d = 37
Is there a way to do this for a structure with any number of fields/variables?
[Note: the function handle can point to one of several functions]
For example:
>> MyStruct.MyFun(X{2}, MyStruct.(X{2}), X{3}, MyStruct.(X{3}), . . . , X{999}, MyStruct.(X{999}))
Any help at all would be greatly appreciated!
Thanks!
0 Comments
Accepted Answer
Stephen23
on 21 May 2020
Edited: Stephen23
on 21 May 2020
>> X = fieldnames(MyStruct);
>> Y = struct2cell(MyStruct);
>> C = [X(2:end),Y(2:end)].'; % assumes that the function is the first field!
>> MyStruct.MyFun(C{:})
Argument a = 1
Argument b = 2
Argument c = 5
Argument d = 37
A more robust solution would be to not use positional input arguments for the function, but write it to accept the structure itself.
3 Comments
Steven Lord
on 21 May 2020
I second the "more robust solution" suggestion. Pass the struct into your functions and let the function itself extract the data it needs from the struct while ignoring the rest.
S = struct('x', 1, 'y', 2, 'z', 3);
timesY = @(x, S) x.*S.y; % ignores S.x and S.z
toPowerZ = @(q, S) q.^(S.z); % ignores S.x and S.y
In fact, if you want your function handles to "remember" S exactly as it existed when the function handle was created (rather than using a struct passed in at run-time), you can simplify this a bit more. If you want to change the S to which the function handles below refer you'll need to recreate those handles.
timesY2 = @(x) x.*S.y;
toPowerZ2 = @(q) q.^(S.z);
More Answers (1)
Bill Tubbs
on 5 Apr 2023
Edited: Bill Tubbs
on 5 Apr 2023
>> MyParams = struct('a',1,'b',2,'c',5,'d',37);
>> MyStruct = struct('Fun',@example,'Params',MyParams);
>> params = namedargs2cell(MyStruct.Params);
>> MyStruct.Fun(params{:})
See Also
Categories
Find more on Argument Definitions in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!