Filter löschen
Filter löschen

How can I use a variable number of structure fields as function arguments?

14 Ansichten (letzte 30 Tage)
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!

Akzeptierte Antwort

Stephen23
Stephen23 am 21 Mai 2020
Bearbeitet: Stephen23 am 21 Mai 2020
Use struct2cell and a comma-separated list:
>> 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 Kommentare
Steven Lord
Steven Lord am 21 Mai 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);

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Bill Tubbs
Bill Tubbs am 5 Apr. 2023
Bearbeitet: Bill Tubbs am 5 Apr. 2023
I recently discovered the function namedargs2cell (since r2019b) and use it for this purpose:
>> MyParams = struct('a',1,'b',2,'c',5,'d',37);
>> MyStruct = struct('Fun',@example,'Params',MyParams);
>> params = namedargs2cell(MyStruct.Params);
>> MyStruct.Fun(params{:})

Kategorien

Mehr zu Structures finden Sie in Help Center und File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by