Accessing complex matlab structure with / string function
I have a matlab structure that has multiple levels (like ab (j) .c (i) .d). I would like to write a function that gives me the fields that I want. If the structure has only one level, this will be easy:
function x = test(struct, label1)
x = struct.(label1)
end
eg. if I have a structure a.b
, I could get b
through: test('b')
. However, this doesn't work with subfields, if I have a struct a.b.c
I can't use test('b.c')
to access it.
Is there a way to pass a string with the fully qualified field name (with dots) to a function to retrieve that field? Or is there an even better way to only get the fields that I select through the function arguments?
Purpose? Of course it would be a useless function for a single field name, but I don't want to pass a list of field names as an argument to get those particular fields.
source to share
You have to use the function subsref
:
function x = test(strct, label1)
F=regexp(label1, '\.', 'split');
F(2:2:2*end)=F;
F(1:2:end)={'.'};
x=subsref(strct, substruct(F{:}));
end
To access a.b.c
you can use:
subsref(a, substruct('.', 'b', '.', 'c'));
The test function first splits the input using .
as delimiter and creates a cell array F
where every other element is filled in .
, and then its elements are passed substruct
in as arguments.
Note that if there are arrays, structs
it will get the first one. For a.b(i).c(j).d
transfer b.c.d
will return a.b(1).c(1).d
. See this question for how to handle it.
As a side note, I renamed your input variable struct
to strct
because it struct
is a MATLAB builtin command.
source to share
One way is to create a self-call function :
a.b.c.d.e.f.g = 'abc'
value = getSubField ( a, 'b.c.d.e.f.g' )
'abc'
function output = getSubField ( myStruct, fpath )
% convert the provided path to a cell
if ~iscell(fpath); fpath = strread ( fpath, '%s', 'delimiter', '.' ); end
% extract the field (should really check if it exists)
output = myStruct.(fpath{1});
% remove the one we just found
fpath(1) = [];
% if fpath still has items in it -> self call to get the value
if isstruct ( output ) && ~isempty(fpath)
% Pass in the sub field and the remaining fpath
output = getSubField ( output, fpath );
end
end
source to share