MATLAB: How to make a function accept structure and fields as separate inputs

custom functionsfieldsfunctionsstructures

I have a structure that is organised something like this:
Subject(index).DataType.DataSubType.means
And I want to run a custom-written function on it.
Part of the function is to loop through all the elements in the structure:
for index = 1:20
%do something to Subject(index).DataType.DataSubType.means
end
I would also like this function to work on different, similarly organised data, e.g. Differentstructure(index).DataType.DataSubType.SDs. Thus I want to be able to give the overall name of the structure ('Subject') and the particular field ('DataType.DataSubType.means') as separate inputs to the function.
Is there a way to do this? I haven't been able to find one. Eval doesn't work, and I'm aware it isn't good practice anyway. If not, how should I organise my function to do this?

Best Answer

You can use dynamic field names for this, but to be honest eval is probably the best solution in this case.
Here it is with dynamic field names. You can use different methods to specify the list of fields to extract (one big string, a cell array, etc.), they're all essentially the same:
function out = iteratestruct(sarr, fieldhierarchy, fun)
%iteratestruct Apply function to subfields of a structure array

%sarr: structure array with fields that match fieldhierarcy

%fieldhierarchy: string indicating which fields to extract. Fields are separated by '.'

%fun: a function handle which takes value from the specified field and return one output

fieldlist = strsplit(fieldhierarcy, '.');
out = cell(size(sarr));
for sidx = 1:numel(sarr) %iterate over structure array
selem = sarr(sidx);
for f = fieldlist %navigate the field hierarchy
selem = surelem.(f{1});
end
out(sidx) = fun(selem); %selem is the required field value
end
end
Whereas with eval:
function out = iteratestruct(sarr, fieldhierarchy, fun)
%iteratestruct Apply function to subfields of a structure array
%sarr: structure array with fields that match fieldhierarcy
%fieldhierarchy: string indicating which fields to extract. Fields are separated by '.'
%fun: a function handle which takes value from the specified field and return one output
out = cell(size(sarr));
for sidx = 1:numel(sarr)
selem = sarr(sidx);
out = eval(sprintf('fun(selem.%s)', fieldhierarchy));
end
end
Code is untested, may have typos or bugs, and of course lacks any kind of input check / argument validation, error handling, etc.