Deleting Elements in a Structure - Error Matrix Index is Out of Range

2 ビュー (過去 30 日間)
John
John 2022 年 8 月 19 日
コメント済み: Voss 2022 年 8 月 22 日
I have a struct with several fields
x.score = [98 75 22 75 29];
x.count = [1 2 3 4 5];
I want to delete all the elements in x (in all fields) that have a count < 4. So in this case I want X to be
x.score = [98 75 22]
x.count = [1 2 3]
Why doesn't this cmd work?
x([x.count<4]) = []
Matrix index is out of range for deletion.
  1 件のコメント
Stephen23
Stephen23 2022 年 8 月 20 日
編集済み: Stephen23 2022 年 8 月 20 日
"Why doesn't this cmd work?"
Because you are mixing up indexing into x (which is a scalar structure) with indexing into the fields of x (which are numeric vectors). If you want to remove elements from the fields of x then you need to index into those fields, and not by attempting to into the scalar structure x. Sometimes it is useful to index into a structure, but not if your goal is to index into its fields!
x.score = [98,75,22,75,29];
x.count = [1,2,3,4,5];
idx = x.count>=4;
x.score(idx) = [];
x.count(idx) = []
x = struct with fields:
score: [98 75 22] count: [1 2 3]
Note that these square brackets are completely superfluous, get rid of them: [x.count<4] Even if x was non-scalar that would still be invalid syntax, so they indicate (as most situations where a user has superfluous square brackets) a confusion about what square brackets do and when to use them:
y(1).count = 1;
y(2).count = 2;
[y.count<4] % square brackets don't do anything useful here either
Error using <
Too many input arguments.

サインインしてコメントする。

採用された回答

Voss
Voss 2022 年 8 月 19 日
編集済み: Voss 2022 年 8 月 22 日
x.score = [98 75 22 75 29];
x.count = [1 2 3 4 5];
x.count<4 is a 1x5 logical array
x.count<4
ans = 1×5 logical array
1 1 1 0 0
x(x.count<4) = [] would try to delete elements 1, 2, 3 of x (where x.count<4 is true), but you can't do that because x only has one element
size(x)
ans = 1×2
1 1
so you get the error.
Instead of deleting elements of x, you want to delete elements of each field of x, which can be done as follows:
f = fieldnames(x);
idx_to_delete = x.count<4;
for ii = 1:numel(f)
x.(f{ii})(idx_to_delete) = [];
end
disp(x)
score: [75 29] count: [4 5]
This gives a result different than what you specified the result should be. Perhaps the condition should be x.count>=4?
x.score = [98 75 22 75 29]; % re-create x
x.count = [1 2 3 4 5];
f = fieldnames(x);
idx_to_delete = x.count>=4;
for ii = 1:numel(f)
x.(f{ii})(idx_to_delete) = [];
end
disp(x)
score: [98 75 22] count: [1 2 3]
  4 件のコメント
John
John 2022 年 8 月 22 日
編集済み: John 2022 年 8 月 22 日
Thanks. I was expecting a way to filter on data with a large number of fields without having to write a loop. Maybe using a table instead of struct is more appropriate. I have a large number of fields that I want to filter on multiple parameters to looks for patterns in a subset of the data.
Voss
Voss 2022 年 8 月 22 日
You're welcome! Yes, a table may be more convenient, or just use a loop.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeStructures についてさらに検索

製品


リリース

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by