从 matlab 中的嵌套结构递归提取数据的最佳做法是什么?

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

我正在尝试以递归方式从嵌套结构中提取一些数据。首先,我知道它有一个字段 (values),它在嵌套结构中重复自身。其次,我知道具有这些值的结构只有作为字段的结构。在下面的代码中,我尝试通过搜索我当前的结构是否有一个名为 values 的字段来访问 structure.values。如果有,我将 .values 放在结构名称的末尾。如果它没有这个字段,我验证是否所有字段都是结构体。如果是,则意味着我将不得不进一步考虑它们并从每个值中提取值。如果字段不是结构,则意味着它们是值,我将它们保存到一个新的简化结构中。我想要的字段示例:S.values.model1.values.mission.values.(alt/list)。目前,使用下面的代码我只能从一个字段中获取值然后我得到一个错误并且不知道如何进一步处理。

代码示例:

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

因为事先知道需要哪些字段,您可以在元胞数组中排列后续的字段名称并使用循环提取值:

names = {'values', 'model1', 'values', 'mission', 'values', 'alt'};
out = S;
for name : names
  out = out.(name{1});
end 

所以这是使用的循环版本:

out = S.values.model1.values.mission.values.alt;

编辑:

如果您想列出所有字段名称和所有字段值,您可以使用这些函数:

function out = names(s, p)
  if isstruct(s)
    out = {};
    f = fieldnames(s);
    for i = 1:numel(f)
      s1 = s.(f{i});
      p1 = [p '.' f{i}];
      out = [out; names(s1, p1)];
    end
  else
    out = {p};
  end
end
  
function out = values(s)  
  if isstruct(s)
    out = {}; 
    f = fieldnames(s);
    for i = 1:numel(f)
      out = [out; values(s.(f{i}))];
    end
  else
    out = {s};
  end
end

将它们用作:

n = names(S, 'S');
v = values(S);