Select elements of a list by comparing it to another list
A rule-based approach:
patt = List /@ OrderlessPatternSequence @@@ Alternatives @@ sub;
Cases[prod, {x_, y : patt} :> {x, y}]
{{"x2", {"e", "f", "g"}}, {"x4", {"m", "n"}}, {"x5", {"o", "p", "q", "r"}}}
And a functional approach:
sel = Outer[ContainsAll, Last /@ prod, sub, 1];
Pick[prod, Or @@@ sel]
{{"x2", {"e", "f", "g"}}, {"x4", {"m", "n"}}, {"x5", {"o", "p", "q", "r"}}}
A simpler one:
select[{label_, values_}] := MemberQ[sub, {OrderlessPatternSequence @@ values}]
Pick[prod, select /@ prod]
{{"x2", {"e", "f", "g"}}, {"x4", {"m", "n"}}, {"x5", {"o", "p", "q", "r"}}}
You can use the same approach with Select
:
Select[prod, select]
{{"x2", {"e", "f", "g"}}, {"x4", {"m", "n"}}, {"x5", {"o", "p", "q", "r"}}}
You can also turn prod
into an Association
using sorted second elements as keys and then use Lookup
:
Lookup[Sort/@sub] @ GroupBy[ Sort@*Last] @ prod
{{{"x4", {"m", "n"}}}, {{"x5", {"o", "p", "q", "r"}}}, {{"x2", {"e", "f", "g"}}}}
Make it a function:
ClearAll[lookUp]
lookUp[keys_] := Lookup[Sort /@ keys] @* GroupBy[Sort@*Last]
lookUp[sub] @ prod
{{{"x4", {"m", "n"}}}, {{"x5", {"o", "p", "q", "r"}}}, {{"x2", {"e", "f", "g"}}}}
getMatches[prod_, sub_] := Module[{test},
Scan[(test[Sort[#]] = True) &, sub];
Cases[prod, {_, y_?test}]]
getMatches[prod, sub]
{{"x2", {"e", "f", "g"}}, {"x4", {"m", "n"}}, {"x5", {"o", "p", "q", "r"}}}
Also
getMatches[prod_, sub_] := Module[{test},
Scan[(test[Sort[#]] = True) &, sub];
Select[prod, test@*Last]]