21 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!

Stephen
on 21 May 2020

Edited: Stephen
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.

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);

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

Start Hunting!