I have two cell arrays of strings as follows
A={{a,b},{c},{d,e}}
B={{a,b},{c,d},{e}}
I want to check if A is a subset of B, meaning that each cell in A has a super-cell in B. In the given example it is not since A contains {d,e} while B does not have any cell that has those or more elements. I think ismember should be useful in this case, but I just could not write down the logic.
Thank you!
Given A and B
A={{'a','b'},{'c'},{'d','e'}}
B={{'a','b'},{'c','d'},{'e'}}
We can define a function isSubset
, as follows:
isSubset = @(superSet,subSet)isempty(setdiff(subSet, superSet));
And test it:
isSubset(B{1}, A{1}) %true
isSubset(B{2}, A{2}) %true
isSubset(B{3}, A{3}) %false
Now we can use isSubSet
and cellfun
to define a function isSubSetOfAny
, which checks to see if a particular subset is a subset of any of a set of sets, like this:
isSubSetOfAny = @(superSetSet, subSet) any(cellfun(@(x)isSubset(x, subSet), superSetSet));
And test it:
isSubSetOfAny(B, A{1}) %True
isSubSetOfAny(B, A{2}) %True
isSubSetOfAny(B, A{3}) %True
Now we can use isSubSetOfAny
plus cellfun
(again) to define isEachMemberASubsetOfAny
, which performs the operation you describe:
isEachMemberASubsetOfAny = @(superSetSet, subSetSet) all(cellfun(@(x)isSubSetOfAny(superSetSet, x), subSetSet));
And test it:
isEachMemberASubsetOfAny(B, A) %Returns false
A_1 = {{'a','b'},{'c'},{'e'}}; %Define a variant of `A`
isEachMemberASubsetOfAny(B, A_1) %Returns false
How about something like:
function tf = is_subset(A,B)
narginchk(2,2)
assert(iscell(A) && all(cellfun(@iscellstr,A)));
assert(iscell(B) && all(cellfun(@iscellstr,B)));
for ia=1:numel(A)
tf = false;
for ib=1:numel(B)
if all(ismember(A{ia},B{ib}));
tf = true;
break
end
end
if ~tf
break
end
end
end
With
[a,b,c,d,e] = deal('1','2','3','4','5');
A = {{a,b},{c},{d,e}};
B = {{a,b},{c,d},{e}};
is_subset(A,B) %# false
B = {{a,b},{c,d,e},{e}};
is_subset(A,B) %# true
Assuming a,b etc are strings you could do the following:
For each cell of A loop through B and see whether there is a cell in B for which all elements in the cell are member. Here is an example:
A={{'abc','b'},{'c'},{'d','e'}};
B={{'aabc','b'},{'c','d'},{'d','e'}}; %Remove the first a to return true
subset = true;
for i = 1:length(A)
found = false;
for j = 1:length(B)
found = found || all(ismember(A{i},B{j}));
end
subset = subset && found;
end
subset
What are the types of a, b, etc.? If they are strings, you can use setdiff
to test whether one set is contained within another. Suitable use of cellfun
and any
or all
should do it. Like so:
all(cellfun(@(a)any(cellfun(@(b)isempty(setdiff(a,b)),B)),A))
If they're some other type, you can make a simple m-file to check for a super-cell. Replace isempty(setdiff(a,b))
with a call to this function. It will have to loop through the elements of a
and check for each one whether it exists in b
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With