# Using select to pick out elements of nested lists in an odd way

Suppose I have a nested list such as,

{{{A, B}, {A, D}}, {{C, D}, {A, A}, {H, A}}, {{A, H}}}


Where the elements of interest are,

{{A, B}, {A, D}}

{{C, D}, {A, A}, {H, A}}

{{A, H}}


How would I use select to pick up only elements that contain two or more As in the first part of their sub-elements. In this example I would want the following as an output,

{{A,B},{A,D}}

-
This does it: Cases[{{{A, B}, {A, D}}, {{C, D}, {A, A}, {H, A}}, {{A, H}}}, {___, {A, _}, ___, {A, _}, ___}] – Coolwater Jul 28 '14 at 19:29
Yep this is exactly what I am looking for. Thank you. – Ibrahim Jul 28 '14 at 19:35

list = {{{a, b}, {a, d}}, {{c, d}, {a, a}, {h, a}}, {{a, h}}}

Pick[list, Count[#[[All, 1]], a] >= 2 & /@ list]


or

Select[list, Count[#[[All, 1]], a] >= 2 &]


or

Cases[list, _?(Count[#[[All, 1]], a] >= 2 &)]


or

DeleteCases[list, _?(! Count[#[[All, 1]], a] >= 2 &)]


all give

{{{a, b}, {a, d}}}

-
This is probably the best answer, since it uses the select command explicitly. Thanks! – Ibrahim Jul 28 '14 at 20:23
@kguler executing your Select with, f.e., list = {{{a, b}, {c, a}}, {{c, d}, {a, a}, {h, a}}, {a, h}, {{a, b}, {a, c}}, {{a, b}, {q, r}, {a, d}}} I get an error message and a result which is, the question being utterly ambigous, debatable. – eldo Jul 28 '14 at 20:37
@eldo, good observation re implicit assumption that is the source of the error message: although OP's example has that structure, it is not explicitly stated that all sublists have depth >=2. However -- removing {a,h} or changing it to {{a,h}} -- I don't understand why the result is "debatable". – kglr Jul 28 '14 at 20:55
@kguler - This question has a short history of accepted and de-accepted answers and comments which were subsequently deleted. "Debatable" because the OP is unsure about what he really wants. Hopefully, your excellent answer stays awarded. (But a Case-solution would be more appropriate imo) :) – eldo Jul 28 '14 at 21:13
@eldo, I see. I missed the deleted comments. And I now see why the wording "elements that contain two or more As in the first part of their sub-elements" could be read differently from my reading of it -- of course, with the help of desired output -- as " two or more elements whose first part is equal to A" – kglr Jul 28 '14 at 21:23
list = {{{A, B}, {A, D}}, {{C, D}, {A, A}, {H, A}}, {{A, H}}};

If[Count[First /@ #, A] >= 2, #, ## &[]] & /@ list


{{{A, B}, {A, D}}}

-

I chose a slightly different formulation:

expr = {{{A, B}, {A, D}}, {{C, D}, {A, A}, {H, A}}, {{A, H}}};

Select[expr, Count[#, {A, _}] > 1 &]

{{{A, B}, {A, D}}}


I will note that this form is faster all four in the Accepted answer:

list = RandomChoice[CharacterRange["A", "H"], {500000, 3, 2}];

Select[list, Count[#, {"A", _}] > 1 &]                  // Timing // First

Pick[list, Count[#[[All, 1]], "A"] >= 2 & /@ list]      // Timing // First
Select[list, Count[#[[All, 1]], "A"] >= 2 &]            // Timing // First
Cases[list, _?(Count[#[[All, 1]], "A"] >= 2 &)]         // Timing // First
DeleteCases[list, _?(! Count[#[[All, 1]], "A"] >= 2 &)] // Timing // First


0.592804

0.795605
0.811205
0.936006
1.060807

-