Deleting or selecting rows of a struct with a condition

7 ビュー (過去 30 日間)
im db d
im db d 2015 年 6 月 29 日
編集済み: James Tursa 2015 年 6 月 29 日
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.

採用された回答

James Tursa
James Tursa 2015 年 6 月 29 日
編集済み: James Tursa 2015 年 6 月 29 日
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

その他の回答 (2 件)

Azzi Abdelmalek
Azzi Abdelmalek 2015 年 6 月 29 日
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 2015 年 6 月 29 日
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'}) = [];

カテゴリ

Help Center および File ExchangeCharacters and Strings についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by