0
votes

As the title says, I would like to copy only certain elements of a structure into a new one, where all copied elements have a specific value in one field.

I have an existing structure S with the fields 'ID', 'Direction', 'Length', 'Width'. The field Direction can have two value: '+' and '-'. I want to create a new structure Sp with all '+' elements and Sn with all '-' elements. Is that possible without a for loop like this?

Sp = struct('ID', '', 'Direction', '', ...);

for ii=1:size(S,1)
   if S(ii).Direction == '+'
      Sp(end+1)=S(ii);
   end
end

Ultimately I need to draw a histogram of the Length and Width, differentiating between the + and - elements. If that is possible without the extra structures, I'd be grateful for any tips!

Thank you very much for helping me!

2
I am not sure if that is possible, but I do not think that this loop is very slow. However, the reason I comment about the == sign. This works fine for a single char, but if you have a vector, the logical operator will compare the full vector, eg 'ab' == 'ac' will give the answer [1,0]. You will also get an error for ab=abc since the vectors have different lengths. As I said this is ok for scalar comparison, but otherwise you may want to use strcmp (or strcmpi case insensitive). - patrik
Ah, yes, that's true, thanks! Matlab also keeps telling me to use strcmp, but I still forget about it every second time.. - Elise

2 Answers

0
votes

I think this is what you're looking for:

S = struct('ID', {1, 2, 3, 4}, ...
           'Direction', {'+', '+', '-', '-'}, ...
           'Length', {1, 2, 3, 4}, ...
           'Width', {1, 2, 3, 4});

S([S.Direction] == '+')

S([S.Direction] == '-')

To extend this a little to your histogram question you could do this:

Sp = S([S.Direction] == '+');
hist([Sp.Length], [Sp.Width]);

Or this if you wanted to do it all in one line (however this might be slower because it is doing the filtering twice):

hist([S([S.Direction] == '+').Length], [S([S.Direction] == '+').Width]);
0
votes

See if this works out for you -

%// Get data from structure, S
data = squeeze(struct2cell(S))

%// Get Direction field values
data_Dir = vertcat(data{strcmp(fieldnames(S),'Direction'),:})

%// Separate out Direction field values into two separate structs as asked for
Sp = struct('Direction',data_Dir(data_Dir=='+'))
Sn = struct('Direction',data_Dir(data_Dir=='-'))