Deleting or selecting rows of a struct with a condition

35 views (last 30 days)
Dear All, I would like to delete or select the rows of a struct by checking the value of a column. For example in the bellow, I say if the value was not 'p' and not 'h', then delete the row.
for i=1:numel(logfile)
if (logfile(i).code ~= 'p') && (logfile(i).code ~= 'H')
logfile(i)=[];
end
end
It only deletes one row, The error that i get is as follow:
Operands to the || and && operators must be convertible to logical scalar values.
Would you please give me some tips?
If i wanted to filter the rows with code value of 'p', then what should I do?
I tried this
logfile([logfile.code == 'p'])
but the error code is as follows :
Index exceeds matrix dimensions.
Thank you in advance.

Accepted Answer

James Tursa
James Tursa on 29 Jun 2015
Edited: James Tursa on 29 Jun 2015
The first part, assuming the .code fields are all 1 character:
logfile_code = [logfile.code]; % Get all the codes
g = logfile_code == 'p' | logfile_code == 'H'; % Find the p and H codes
logfile = logfile(g); % Select only the p and H codes, delete the rest
The second part:
g = logfile_code == 'p'; % Find the p codes
logfile_p = logfile(g); % Select only the p code rows
If the .code fields could be any length string and not single characters, then you could use a cell array of strings instead. E.g.,
logfile_code = {logfile.code};
g = strcmp(logfile_code,'p') | strcmp(logfile_code,'H');
logfile = logfile(g); % Select only the p and H codes, delete the rest
and
g = strcmp(logfile_code,'p');
logfile_p = logfile(g); % Select only the p code rows

More Answers (2)

Azzi Abdelmalek
Azzi Abdelmalek on 29 Jun 2015
Don't use ==
for i=1:numel(logfile)
if ~isequal(logfile(i).code,'p') && ~isequal(logfile(i).code,'H')
logfile(i)=[];
end
end

Guillaume
Guillaume on 29 Jun 2015
Most likely, you're getting the error with && because some of your code strings are more than one character. See the output of:
'xyz' ~= 'p'
As a rule, if you're going to compare strings always use strcmp (or its companions strcmpi, strncmp, strncmpi) which will always return a scalar regardless of the length of the string. So,
if ~strcmp(logfile(i).code,'p') && ~strcmp(logfile(i).code, 'H')
will fix your problem.
But you're using a loop, and that's not efficient. You were on the right track with your other expression. Again, you should be using strcmp and you should concatenate all the codes into a cell array rather than a vector, so:
logfile(~strcmp({logfile.code}, 'p') & ~strcmp({logfile.code}, 'H')) = [] %no need for loop
Finally, rather than doing two strcmp, you can use ismember (which uses strcmp internally), so it becomes:
logfile(~ismember({logfile.code}, {'p', 'H'}) = [];

Categories

Find more on Characters and Strings in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!