How do I verify if a structure array is a subset of another structure array

15 vues (au cours des 30 derniers jours)
Cahit Ugur
Cahit Ugur le 29 Avr 2022
Commenté : Jan le 29 Avr 2022
Hi,
I have two structure arrays (S1 & S2) each are nested structure arrays and I want to verify, if S1 is a sub-set of S2. The sub-set criterion are:
  • every field in S1 should exist in S2. Other way around is not necessary. This check should take the levels in nested structure into account.
  • every data on the commonly existing fields (unless it is a structure array) should be equal.
Let's take the below structures as an example:
S1.f1 = 'text';
S1.f2 = 3;
S1.f3 = struct('subF1', 0, 'subF2', 'some text');
S1.subF3 = 'extra';
S2.f1 = 'text';
S2.f2 = 3;
S2.f3 = struct('subF1', 0, 'subF2', 'some text', 'subF3', 'extra');
S2.f4 = 'also extra';
Based on the above criterion, the verification should check the following fields and data in them:
  • S1.f1 === S2.f1
  • S1.f2 === S2.f2
  • S1.f3.subF1 === S2.f3.subF1
  • S1.f3.subF2 === S2.f3.subF2
All of the above fields are common and in the same level in the nested structures. Although the field 'subF3' exists in both S1 and S2, the level in the nested structure is wrong. Therefore, it is not a common field and should cause the verification to fail.
For verification I use the matlab.unittest framework, however there is no fitting contraint to my need. The closest to what I need is the matlab.unittest.constraints.IsSubsetOf constraint, which unfortunately does not support struct types.
The workaround that I can think of is to extract the fields from S2, which exist in S1 and use the matlab.unittest.constraints.IsEqualTo constraint for the verification.
import matlab.unittest.TestCase
import matlab.unittest.constraints.IsEqualTo
testCase = TestCase.forInteractiveUse;
S2extracted = S2('allTheFieldsExistingInS1');
testCase.verifyThat(S1, IsEqualTo(S2extracted));
How can I implement the algoritm for the extraction of the fields including sub-fields?
or, is there a better way of completing the task?
  3 commentaires
Rik
Rik le 29 Avr 2022
You should also watch out for values that are not equal to themselves. You might be interested in a function like ComputeNonCryptHash.
isequal(NaN,NaN)
ans = logical
0
Cahit Ugur
Cahit Ugur le 29 Avr 2022
I have updated the description. I hope the "sub-set" concept is clearer now.

Connectez-vous pour commenter.

Réponse acceptée

Jan
Jan le 29 Avr 2022
Modifié(e) : Jan le 29 Avr 2022
You have to write your own tool to test for your definition of a struct-subset. Maybe:
% [UNTESTED CODE]
function T = isStructSubset(A, B)
T = true; % Default
fA = fieldnames(A);
for k = 1:numel(fA)
dA = A.(fA{k});
if ~isfield(B, fA{k}) % B does not contain this field
T = false;
elseif isstruct(dA) % This field is a struct
dB = B.(fA{k});
if isstruct(dB) % Must be a struct in B also
T = isStructSubset(dA, dB); % [EDITED], argumentes swapped
else
T = false;
end
else % dA is not a struct:
T = isequal(B.(fA{k}), dA);
end
if ~T % Return at the first difference
return;
end
end
end
  2 commentaires
Cahit Ugur
Cahit Ugur le 29 Avr 2022
Thank you for the help!
Except a tiny bug (parameter order in the recursive function call), it is perfect!
I attach the corrected code, in case someone else needs it:
% [UNTESTED CODE]
function T = isStructSubset(A, B)
T = true; % Default
fA = fieldnames(A);
for k = 1:numel(fA)
dA = A.(fA{k});
if ~isfield(B, fA{k}) % B does not contain this field
T = false;
elseif isstruct(dA) % This field is a struct
dB = B.(fA{k});
if isstruct(dB) % Must be a struct in B also
T = isStructSubset(dA, dB);
else
T = false;
end
else % dA is not a struct:
T = isequal(B.(fA{k}), dA);
end
if ~T % Return at the first difference
return;
end
end
end
Jan
Jan le 29 Avr 2022
I've fixed the bug in my code. Maybe a test for struct arrays is required also: the current version works for scalar structs only.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Structures dans Help Center et File Exchange

Produits


Version

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by