What is the best practice to recursively extract data from a nested structure in matlab?

20 views (last 30 days)
Moon Diver
Moon Diver on 12 Jan 2022
Commented: Moon Diver on 14 Jan 2022
I'm trying to exctract some data from a nested structure in a recursive manner. First, I know that this has a field (values) which repeats itself inside the nested structure. Secondly I know that the structure which has those values has only structures as fields. In the below code I've tried to acces the structure.values by searching if my current structure has a field named values. If it has I put .values at the end of my structure name. If it doesn't have this field, I verify if all the fields are structures. If the are it means that I will have to consider them further and to extract the values from each one. If the fields are not structures it means that they are values and I save them into a new simplified structure.( Example of fields that I want(S.values.model1.values.mission.values.(alt/list) Currently, with the bellow code I'm only able to get the values from one field and then I get an error and don't know how to approach further.
Code example:
clear all
clc
S=struct()
S.case='1';
S.type='A';
S.values.model1.case='2'
S.values.model1.type='C'
S.values.model1.values.mission.case='3'
S.values.model1.values.mission.type='D'
S.values.model1.values.mission.values.alt='none'
S.values.model1.values.mission.values.list=2
S.values.model1.values.mission.values.parameter=4
S.values.model1.values.phase.case='4'
S.values.model1.values.phase.type='A'
S.values.model1.values.phase.values.num='all'
S.values.model1.values.phase.values.eq=2
S.values.model1.values.phase.values.unit=4
S.values.model1.values.analysis.case='1'
S.values.model1.values.phase.type='A'
S.values.model1.values.phase.values.nump1.list='all'
S.values.model1.values.phase.values.nump1.table='four'
S.values.model1.values.phase.values.nump1.mean=0
S.values.model1.values.phase.values.nump2.list='none'
S.values.model1.values.phase.values.nump2.table='three';
S.values.model1.values.phase.values.nump2.mean=1
s=S.values.model1;
names=fieldnames(s);
nnames=numel(names);
newStruct={};
[valsi,newstructi]=extractValues(names,s,nnames,newStruct)
function [vals,newStruct]=extractValues(names,vals,nnames,newStruct)
if any(strcmp(names,'values'))
vals=vals.('values');
names=fieldnames(vals)
nnames=numel(names)
[vals,newStruct]=extractValues(names,vals,nnames,newStruct);
end
for j=1:nnames
value(j)=isstruct((vals.(names{j})));
end
if all(value)
for k=1:nnames
vals=(vals.(names{k}));
names=fieldnames(vals);
nnames=numel(names);
[vals,newStruct]=extractValues(names,vals,nnames,newStruct);
end
else
for j=1:nnames
value=(vals.(names{j}));
newStruct.(names{j})=value;
end
end
end
  4 Comments
Moon Diver
Moon Diver on 14 Jan 2022
I get them this way with the mention that I need to extract de values from the last values field. Not really a logic thing, but those are the instructions.

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 12 Jan 2022
Edited: Stephen23 on 12 Jan 2022
S=struct();
S.case='1';
S.type='A';
S.values.model1.case='2';
S.values.model1.type='C';
S.values.model1.values.mission.case='3';
S.values.model1.values.mission.type='D';
S.values.model1.values.mission.values.alt='none';
S.values.model1.values.mission.values.list=2;
S.values.model1.values.mission.values.parameter=4;
S.values.model1.values.phase.case='4';
S.values.model1.values.phase.type='A';
S.values.model1.values.phase.values.num='all';
S.values.model1.values.phase.values.eq=2;
S.values.model1.values.phase.values.unit=4;
S.values.model1.values.analysis.case='1';
S.values.model1.values.phase.type='A';
S.values.model1.values.phase.values.nump1.list='all';
S.values.model1.values.phase.values.nump1.table='four';
S.values.model1.values.phase.values.nump1.mean=0;
S.values.model1.values.phase.values.nump2.list='none';
S.values.model1.values.phase.values.nump2.table='three';
S.values.model1.values.phase.values.nump2.mean=1;
Z = mainfun(S)
Z = struct with fields:
alt: 'none' list: 2 parameter: 4 num: 'all' eq: 2 unit: 4 nump1: [1×1 struct] nump2: [1×1 struct]
Z.alt
ans = 'none'
Z.nump1.list
ans = 'all'
Z.nump2.list
ans = 'none'
function B = mainfun(A)
B = struct();
nestfun(A,{})
function nestfun(D,C)
if isstruct(D)
F = fieldnames(D);
for k = 1:numel(F)
if nnz(strcmpi(C,'Values'))==3
B.(F{k}) = D.(F{k});
else
nestfun(D.(F{k}),[C,F(k)])
end
end
end
end
end

More Answers (0)

Community Treasure Hunt

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

Start Hunting!