Search code examples
matlabcell-array

Concatenating (sub)fields of structs in a cell array


I have a Matlab object, that is a cell array containting structs that have almost identical structures and I want to programmatically get a (sub)field of the structs of all cell array elements.

For example, we take test

test = {struct('a',struct('sub',1)), struct('a',struct('sub',2),'b',1)};

This will create a cell array with the following structure:

cell-element 1: a --> sub --> 1
cell-element 2: a --> sub --> 2
                  \-> b --> 1

It can be seen that the elements of test don't have the exact same structure, but similar. How can I get all values of the a.sub fields of the elements of the cell. I can obtain them in this specific problem with

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

but I can't quite get this method to work in a more general context (ie. having different fields).


Solution

  • You may want to use the function 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);
    

    In case your data cannot guarantee that all the elements are the same type and size, then you need to output a cell array instead:

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

    Later Edit

    If one wants to use different sets of nested fields for each cell element then:

    %//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);