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,

  • 2
    $\begingroup$ This does it: Cases[{{{A, B}, {A, D}}, {{C, D}, {A, A}, {H, A}}, {{A, H}}}, {___, {A, _}, ___, {A, _}, ___}] $\endgroup$ – Coolwater Jul 28 '14 at 19:29
  • $\begingroup$ Yep this is exactly what I am looking for. Thank you. $\endgroup$ – 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]


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


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


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

all give

{{{a, b}, {a, d}}}
|improve this answer|||||
  • $\begingroup$ This is probably the best answer, since it uses the select command explicitly. Thanks! $\endgroup$ – Ibrahim Jul 28 '14 at 20:23
  • $\begingroup$ @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. $\endgroup$ – eldo Jul 28 '14 at 20:37
  • $\begingroup$ @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". $\endgroup$ – kglr Jul 28 '14 at 20:55
  • $\begingroup$ @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) :) $\endgroup$ – eldo Jul 28 '14 at 21:13
  • $\begingroup$ @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" $\endgroup$ – kglr Jul 28 '14 at 21:23

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



|improve this answer|||||
list = {{{A, B}, {A, D}}, {{C, D}, {A, A}, {H, A}}, {{A, H}}};

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

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

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.