Conditionally select from array of struct by membership of a list in struct element

9 views (last 30 days)
Here's my array of structs:
X(1).Members=[1 2]
X(1).Name="Group 1"
X(2).Members=[2 3]
X(2).Name="Group 2"
Here's the conditional selection form I'm familiar with. I'm hoping there's a better way to express this:
A=[X(ismember(1,[X.Members])).Name]
A = "Group 1"
A=[X(ismember(2,[X.Members])).Name]
A = "Group 1"
A=[X(ismember(3,[X.Members])).Name]
A = "Group 1"
A=[X(ismember(4,[X.Members])).Name]
A = []
Since the 'ismember' operator returns a logical, the expression as formed returns the index of X to 0 or 1.
I would like to apply an expression to X and return each struct in X where a member is in the list of Members in the struct.
  1 Comment
Stephen23
Stephen23 on 22 Jan 2021
Edited: Stephen23 on 22 Jan 2021
The 2nd and 3rd example outputs seem a bit strange:
  • 2nd: the value 2 is a member of both "Group 1" and "Group 2", why does the output only show "Group 1"?
  • 3rd: the value 3 is only a member of "Group 2", why does the output show "Group 1"?

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 22 Jan 2021
Edited: Stephen23 on 22 Jan 2021
X(1).Members = [1,2];
X(1).Name = 'Group 1';
X(2).Members = [2,3];
X(2).Name = 'Group 2';
F = @(n)arrayfun(@(s)any(s.Members==n),X);
F(1)
ans = 1x2 logical array
1 0
F(2)
ans = 1x2 logical array
1 1
F(3)
ans = 1x2 logical array
0 1
F(4)
ans = 1x2 logical array
0 0
If you really want to use ismember, replace the anonymous function with this:
@(s)ismember(n,s.Members)

More Answers (1)

Rick Nickle
Rick Nickle on 22 Jan 2021
Thanks Stephen Cobeldick, that function works well, very much appreciated!
Example usage:
A=[X(F(2)).Name]
A =
1×2 string array
"Group 1" "Group 2"
B=[X(F(2))]
B =
1×2 struct array with fields:
Members
Name
% Checking actual content...
struct2table(B)
ans =
2×2 table
Members Name
_______ _________
1 2 "Group 1"
2 3 "Group 2"
C=[X(F(3))]
C =
struct with fields:
Members: [2 3]
Name: "Group 2"
struct2table(C)
ans =
1×2 table
Members Name
_______ _________
2 3 "Group 2"
  1 Comment
Rick Nickle
Rick Nickle on 22 Jan 2021
Adding a variant to show selecting by multiple fields with Stephen's suggestion:
X(1).Members=1
X(1).Owners=2
X(1).Name="Group 1"
X(2).Members=1
X(2).Owners=1
X(2).Name="Group 2"
Q=@(n,o)arrayfun(@(s)any(s.Members==n && s.Owners==o),X)
Y=[X(Q(1,1))]

Sign in to comment.

Categories

Find more on Structures in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!