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.

+3


source to share


2 answers


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.

+1


source


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

      

+1


source







All Articles