Recursively create structure fields or (maybe) cell2struct

19 次查看(过去 30 天)
Hey Matlab experts,
I am trying to be smart and create a structure as follows
ts.child1.child2 = 'sthg';
The depth of the structure is defined by the length of an array of cells and the field names are defined by the content of this array
fields = {'child1','child2'}
I don't want to "lock" the code with a fix number of for-loops as the numel(fields) can vary from 2 to N.
I have been testing a bit some ideas looking at the Answers in here, but I didn't find anything that didn't use a number of for loops defined by the numel(fields). I would like the idea below but adding the new fields in depth , not flat.
for iR = 1 : numel(fields), ts.(fields{iR}) = ''; end
ts =
struct with fields:
child1: ''
child2: ''
The result we want is
>> ts
struct with fields:
child1: [1×1 struct]
>> ts.child1
struct with fields:
child2: 'sthg'
The general idea is to read through a hierarchy (cell array) and create a structure from it
% Input : cell array
ans =
4×3 cell array
'White matter' '' ''
'' 'CC' ''
'' 'AC' ''
'' '' 'AC_AP'
% Expected output
ts = struct('name','white matter', 'children',[struct('name','CC','children',''),struct('name','AC','children',struct('name','AC_AP'))]);
Is cell2struct what I should be focusing on here ?
Thanks in advance for your help

回答(1 个)

Stephen23
Stephen23 2017-9-22
编辑:Stephen23 2018-1-19
You might be interested in reading about non-scalar structures:
Method one: setfield and getfield:
Both setfield and getfield work with an arbitrary depth of nested structures (and indexing), all you need to do is supply each fieldname as an input (and when using setfield also with the data at the end):
>> S = struct();
>> S = setfield(S,'child1','child2','something');
>> S = setfield(S,'child1','hello1','world2','different');
>> S.child1.child2
ans = something
>> S.child1.hello1.world2
ans = different
In your case (where the fieldnames are in a cell array) you can supply them as a comma-separated list with the data variable at the end:
setfield(S,fields{:},data)
Method two: recursive function:
If you really are determined to do-it-yourself (which I do not recommend), then something like this should get you started. It adds all required substructures and allocates the data at the end:
function S = recfield(S,data,varargin)
S = recfun(S,data,varargin{1},varargin(2:end));
end
function S = recfun(S,data,fld,C)
if isempty(C)
S.(fld) = data;
else
if ~isfield(S,fld)
S.(fld) = struct();
end
S.(fld) = recfun(S.(fld),data,C{1},C(2:end));
end
end
And in use:
>> S = struct();
>> S = recfield(S,'something','child1','child2');
>> S = recfield(S,'different','child1','hello1','world2');
>> S.child1.child2
ans = something
>> S.child1.hello1.world2
ans = different
Note that it will simply overwrite any existing data in the same location.
  2 个评论
ChrCoello
ChrCoello 2017-9-22
Hi Stephen,
Amazing starting point you are giving me here. Running
T=recfield(T,'test3',fields{:})
will allow to work with any depth.
I am integrating this to my code and I'll post here a complete solution.
Thanks,
Christopher

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Structures 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by