Deleting specific values of fields inside a struct array

17 visualizzazioni (ultimi 30 giorni)
Hello everyone,
I have a struct array with multiple fields. All fields are arrays with the same length.
a=struct();
a.field1=rand(20,1);
a.field2=rand(20,1);
a.field3=rand(20,1);
Is there away to delet a specific element from all field arrays at the same time?
So for example delete element 3 from field1, field2 and field3 under specific conditions, for example when field3 value==0.5.
I just know this way:
a.field1(a.field3==0.5)=[];
a.field2(a.field3==0.5)=[];
a.field3(a.field3==0.5)=[];
But is it possible to do this in on line instead of handling every field seperatly?
Best regrads
Marc
  1 Commento
Stephen23
Stephen23 il 2 Mag 2020
"But is it possible to do this in on line instead of handling every field seperatly?"
You could use a loop or structfun (which just hides the loop inside).
Note that comparing floating point numbers for exact equality is a common cause of bugs, you should probably compare the absolute difference against a tolerance:
idx = abs(A-B)<tol

Accedi per commentare.

Risposta accettata

Ameer Hamza
Ameer Hamza il 2 Mag 2020
Modificato: Ameer Hamza il 2 Mag 2020
Something like this
a=struct();
a.field1=rand(20,1);
a.field2=rand(20,1);
a.field3=rand(20,1);
mask = a.field3==a.field3(5); % a.field3(5) is used as example
a = cell2struct(structfun(@(x) {x(~mask)}, a), fieldnames(a));
Result:
>> a
a =
struct with fields:
field1: [19×1 double]
field2: [19×1 double]
field3: [19×1 double]
An alternative way is to use the for-loop. It will probably be faster than the above code because it does not need to create a temporary cell array and recreate the struct.
mask = a.field3==a.field3(5);
names = fieldnames(a);
for i=1:numel(names)
a.(names{i})(mask) = [];
end
Note: If you are going to set the value for comparison with a.field3 arbitrarily, i.e., the comparison value is not already an element of the a.field3 itself. The comparison == for floating-point value can fail. In that case, you can define the mask based on tolerance.
mask = abs(a.field3 - 0.5) < 1e-6; % 1e-6 is the tolerance for the comparison with 0.5
  5 Commenti
Ameer Hamza
Ameer Hamza il 2 Mag 2020
Good point. I assumed that the comparison value would be taken out of the vector itself, e.g., using min(), max(), etc. But if some other operations are performed on the value, then the == comparison can fail.
Marc Laub
Marc Laub il 5 Mag 2020
Its ok,
I modified it anyway to:
mask = a.field3==2;
since my trigger value isalways 2, so its fine.

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Structures in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by