How do I verify if a structure array is a subset of another structure array
13 views (last 30 days)
Show older comments
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 Comments
Rik
on 29 Apr 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)
Accepted Answer
Jan
on 29 Apr 2022
Edited: Jan
on 29 Apr 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 Comments
Jan
on 29 Apr 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.
More Answers (0)
See Also
Categories
Find more on Get Started with MATLAB in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!