Effacer les filtres
Effacer les filtres

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

1 vue (au cours des 30 derniers jours)
John
John le 19 Août 2022
Commenté : Voss le 22 Août 2022
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 commentaire
Stephen23
Stephen23 le 20 Août 2022
Modifié(e) : Stephen23 le 20 Août 2022
"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.

Connectez-vous pour commenter.

Réponse acceptée

Voss
Voss le 19 Août 2022
Modifié(e) : Voss le 22 Août 2022
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 commentaires
John
John le 22 Août 2022
Modifié(e) : John le 22 Août 2022
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 le 22 Août 2022
You're welcome! Yes, a table may be more convenient, or just use a loop.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Structures dans Help Center et File Exchange

Produits


Version

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by