matlabstructmatlab-struct

Extract fields from Structure Array to put into another Structure Array


I have a structure array with a large number of fields that I don't care about, so I want to extract the limited number of fields I DO care about and put it into a separate structure array.

For a structure array of size one, I've done this by creating the new array from scratch, for example:

structOld.a = 1;
structOld.b = 2;
structOld.usefulA = 'useful information';
structOld.usefulB = 'more useful information';
structOld.c = 3;
structOld.d = 'words';

keepFields = {'usefulA','usefulB'};

structNew = struct;
for fn = keepFields
    structNew.(fn{:}) = structOld.(fn{:});
end

which gives

structNew = 

    usefulA: 'useful information'
    usefulB: 'more useful information'

Is there a more efficient way of doing this? How can I scale up to an structure array (vector) of size N?

N = 50;
structOld(1).a = 1;
structOld(1).b = 2;
structOld(1).usefulA = 500;
structOld(1).usefulB = 'us';
structOld(1).c = 3;
structOld(1).d = 'ef';
structOld(2).a = 4;
structOld(2).b = 5;
structOld(2).usefulA = 501;
structOld(2).usefulB = 'ul';
structOld(2).c = 6;
structOld(2).d = 'in';
structOld(3).a = 7;
structOld(3).b = '8';
structOld(3).usefulA = 504;
structOld(3).usefulB = 'fo';
structOld(3).c = 9;
structOld(3).d = 'rm';
structOld(N).a = 10;
structOld(N).b = 11;
structOld(N).usefulA = 506;
structOld(N).usefulB = 'at';
structOld(N).c = 12;
structOld(N).d = 'ion';

In this case, I'd like to end up with:

structNew = 

1x50 struct array with fields:

    usefulA
    usefulB

Keeping elements with empty usefulA/usefulB fields is fine; I can get rid of them later if needed.

Using rmfield isn't great because the number of useless fields far outnumbers the useful fields.


Solution

  • You can create a new struct array using existing data as follows:

    structNew = struct('usefulA',{structOld.usefulA},'usefulB',{structOld.usefulB});
    

    If you have an arbitrary set of field names that you want to preserve, you could use a loop as follows. Here, I'm first extracting the data from strcutOld into a cell array data, which contains each of the arguments the the struct call in the previous line of code. data{:} is now a comma-separated list of these arguments, the last line of code below is identical to the line above.

    keepFields = {'usefulA','usefulB'};
    data = cell(2,numel(keepFields));
    for ii=1:numel(keepFields)
       data{1,ii} = keepFields{ii};
       data{2,ii} = {structOld.(keepFields{ii})};
    end
    structNew = struct(data{:});