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

1 Ansicht (letzte 30 Tage)
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 Kommentar
Stephen23
Stephen23 am 22 Jan. 2021
Bearbeitet: Stephen23 am 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"?

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Stephen23
Stephen23 am 22 Jan. 2021
Bearbeitet: Stephen23 am 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)

Weitere Antworten (1)

Rick Nickle
Rick Nickle am 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 Kommentar
Rick Nickle
Rick Nickle am 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))]

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Structures finden Sie in Help Center und File Exchange

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by