Matlab 连接单元数组中结构的(子)字段

Matlab 连接单元数组中结构的(子)字段,matlab,cell-array,Matlab,Cell Array,我有一个Matlab对象,它是一个包含结构几乎相同的单元数组,我想通过编程获得所有单元数组元素的结构的(子)字段 例如,我们采用test test = {struct('a',struct('sub',1)), struct('a',struct('sub',2),'b',1)}; 这将创建具有以下结构的单元阵列: cell-element 1: a --> sub --> 1 cell-element 2: a --> sub --> 2

我有一个Matlab对象,它是一个包含结构几乎相同的单元数组,我想通过编程获得所有单元数组元素的结构的(子)字段

例如,我们采用
test

test = {struct('a',struct('sub',1)), struct('a',struct('sub',2),'b',1)};
这将创建具有以下结构的单元阵列:

cell-element 1: a --> sub --> 1
cell-element 2: a --> sub --> 2
                  \-> b --> 1
可以看出,
test
的元素没有完全相同的结构,但有相似之处。如何获取单元格元素的
a.sub
字段的所有值。在这个具体问题上,我可以用

acc=zeros(1,numel(test));
for ii=1:numel(test)
   acc(ii) = test{ii}.a.sub;
end

但是我不能让这种方法在更一般的环境下工作(即,具有不同的字段)。

我已经找到了一种方法,使用
eval

function out = catCellStructSubField(cellStruct, fieldName)
out = zeros(1,numel(cellStruct));
for ii = 1:numel(cellStruct)
   out(ii) = eval(['cellStruct{ii}.' fieldName]);
end
在我的测试示例中可以使用它,如下所示:

catCellStructSubField(test, 'a.sub')
动态字段名(
cellStruct{ii}.(fieldName)
)不起作用,因为我正在访问子字段

我知道评估通常是个坏主意。我对不同的解决方案很好奇。

编辑:不需要递归,如@CST link:s的答案所示;本机
getfield
函数可以整齐地展开字段的单元格数组作为其第二个参数,例如
getfield(foo{i},fields{:})
,而不是在下面的旧答案中调用递归函数。然而,我将在下面留下递归解决方案,因为它在问题的上下文中可能有一些价值


您可以构建自己的递归版本的
getField
,使用字段的单元格数组

function value = getFieldRec(S,fields)
  if numel(fields) == 1 
    value = getfield(S, fields{1});
  else
    S = getfield(S,fields{1})
    fields{1} = [];
    fields = fields(~cellfun('isempty',fields));
    value = getFieldRec(S,fields);
  end
end
用法示例:

foo = {struct('a',struct('sub',1)), ...
  struct('a',struct('sub',2),'b',3), ...
  struct('c',struct('bar',7),'u',5)};
accessFields = {'a.sub', 'b', 'c.bar'};

values = zeros(1,numel(foo));
for i = 1:numel(foo)
  fields = strsplit(accessFields{i},'.');
  values(i) = getFieldRec(foo{i},fields);
end
结果如下

values =

     1     3     7

您可能需要使用函数
getfield

%//Data to play with
test = {struct('a',struct('sub',1)), struct('a',struct('sub',2),'b',1)};

%//I'm interested in these nested fields
nested_fields = {'a', 'sub'};

%//Scan the cell array to retrieve the data array
acca = cellfun(@(x) getfield(x, nested_fields{:}), test);
如果数据不能保证所有元素的类型和大小相同,则需要输出单元格数组:

%//Scan the cell array to retrieve the data cell array
accc = cellfun(@(x) getfield(x, nested_fields{:}), test, 'UniformOutput', false);
以后编辑

如果希望为每个单元格元素使用不同的嵌套字段集,则:

%//nested_fields list should have the same size as test
nested_fields = {{'a','sub'}, {'b'}};
accm = cellfun(@(x,y) getfield(x,y{:}), test, nested_fields, 'UniformOutput', false);

你说的“有不同的领域”是什么意思?不同类型的字段值?不同的字段名?我的意思是,不是访问访问不同字段的每个元素的字段
.a.sub
,例如
.some.thing.else
(我的小示例单元格数组中没有包含这些内容)看看
getfield
函数:
getfield
或多或少等同于动态字段名
。(可变)
并且不能处理像
a.sub
这样的字段名。因此,如果不在
上拆分
a.sub
,我就不能直接使用它。好吧,也许我应该把它放在一个答案中……如果我们想访问嵌套字段
a.sub
,而只访问第二个结构的
b
,该怎么办?编辑:啊,可以
嵌套的_字段{:}
会自动为我们处理这个问题吗?很好!@dfri取决于您想如何表达它。但是好的,我会更新这个案例的答案。