How to pick out the element in a list of lists which satisfies a particular condition?
A more mathematically intuitive formulation would be to use Intersection
, as then the logic is self-explanatory. You can also create a custom container to make the sets orderless so that {1,2,3}
, {3,1,2}
and {2,3,1}
are all treated the same (alternately, you can use Sort
). For example:
equivalentQ[func_] := Block[{f},
SetAttributes[f, Orderless];
With[{set = # /. List -> f},
Intersection[set, func@# /. List -> f] === set
]
] &;
Sets that equal those transformed by func
should yield True
. With this, you can write your condition as
cond = equivalentQ[Mod[# + 2, 4, 1] &]
(and easily extend it to other transformation functions).
Select
:Select[list, cond] (* {{{1, 2, 3, 4}}, {{1, 2}, {3, 4}}, {{1, 3}, {2}, {4}}, {{1, 4}, {2, 3}}, {{1}, {2, 4}, {3}}, {{1}, {2}, {3}, {4}}} *)
Cases
:Cases[list, x_List /; cond[x]]
Pick
:Pick[list, cond /@ list]
Reap
&Sow
:Last@Reap@Scan[If[cond[#], Sow[#]] &, list]
If my reading of your question is correct, this does the job:
sets = {{{1, 2, 3, 4}}, {{1, 2, 3}, {4}}, {{1, 2, 4}, {3}}, {{1, 2}, {3, 4}},
{{1, 2}, {3}, {4}}, {{1, 3, 4}, {2}}, {{1, 3}, {2}, {4}},
{{1, 4}, {2, 3}}, {{1}, {2, 3, 4}}, {{1}, {2, 3}, {4}},
{{1, 4}, {2}, {3}}, {{1}, {2, 4}, {3}}, {{1}, {2}, {3, 4}},
{{1}, {2}, {3}, {4}}};
Cases[sets, list_List /; Equal @@ Map[Sort, {list, Mod[list + 2, 4, 1]}, 2]]
{{{1, 2, 3, 4}}, {{1, 2}, {3, 4}}, {{1, 3}, {2}, {4}},
{{1, 4}, {2, 3}}, {{1}, {2, 4}, {3}}, {{1}, {2}, {3}, {4}}}
I failed to spell out a working solution for your problem the first time. Here is what I intended:
sortall = # /. List :> Composition[Sort, List]&;
Select[lis, sortall @ # === sortall @ Mod[# + 2, 4, 1] &]
{{{1, 2, 3, 4}}, {{1, 2}, {3, 4}}, {{1, 3}, {2}, {4}}, {{1, 4}, {2, 3}}, {{1}, {2, 4}, {3}}, {{1}, {2}, {3}, {4}}}
J.M.'s method is cleaner, and in this case without a downside that I can see. (The sortall
function is useful if you want to sorts Lists and only Lists at any level in an expression.) I still prefer Select
here:
Select[lis, Equal @@ Map[Sort, {#, Mod[# + 2, 4, 1]}, 2] &]