# The correct pattern for Cases

I have a problem that, admittedly, I have already solved using Select instead, but it is irking me that I cannot seem to construct the right pattern to solve it using Cases. I would like the output of

Cases[
{{{1, 2}, {3}, {4, 5}}, {{6}, {}}, {{}, {}}},
(* THE CORRECT PATTERN HERE *)
]


to be

{{{1, 2}, {3}, {4, 5}}, {{6}, {}}}


In other words, I would like a pattern that picks up all the elements of the outer list that have at least one non-empty list as an element.

• Do you want to do like this. Cases[ {{{1, 2}, {3}, {4, 5}}, {{6}, {}}, {{}, {}}}, Except[{{}, {}}]] Aug 28, 2014 at 0:31

list = {{{1, 2}, {3}, {4, 5}}, {{6}, {}}, {{}, {}}};
Cases[list, Except[{{} ..}]]
(* {{{1, 2}, {3}, {4, 5}}, {{6}, {}}} *)


or

Cases[list, {___, Except[{}], ___}]
(* {{{1, 2}, {3}, {4, 5}}, {{6}, {}}} *)


You can also use PatternTest (_?func) where func is any selector function that you might have used as the second argument of Select. For example:

Select[list, Union @@ # =!= {} &]  (* or Flatten @ # =!= {} & or  ... *)
(* {{{1, 2}, {3}, {4, 5}}, {{6}, {}}}  *)

Cases[list, _?(Union @@ # =!= {} &)]
(*  {{{1, 2}, {3}, {4, 5}}, {{6}, {}}} *)

• Oh, wow! I didn't realize the solution would be that simple. Thank you very much. Aug 28, 2014 at 0:25
• @Shredderroy, my pleasure.
– kglr
Aug 28, 2014 at 0:35
• @kguler so good ...
– eldo
Aug 28, 2014 at 0:48
• Cases[list, {___, {__}, ___}] seems simpler and faster. Aug 28, 2014 at 1:29
• @MichaelE2, that is surprising! Makes you think; I wouldn't have expected it to work; now i think i see why it works ... -- which makes pattern puzzles such fun :) I would be happy to add to my answer but I think you should post it as a separate answer.
– kglr
Aug 28, 2014 at 2:08

Here's a way, that is a bit like @kguler's, but it's simpler and a little faster:

list = {{{1, 2}, {3}, {4, 5}}, {{6}, {}}, {{}, {}}};

Cases[list, {___, {__}, ___}]
(*
{{{1, 2}, {3}, {4, 5}}, {{6}, {}}}
*)


The pattern ___ (three underscores or BlankNullSequence) matches zero or more things and the pattern __ (two underscores or BlankSequence) matches one or more things. So the pattern {___, {__}, ___} represents a list containing

1. zero or more things, followed by
2. a list containing at least one thing, followed by
3. zero or more of things.

All in all, it matches a list that contains at least one element that is a nonempty list. Cases will match this against the elements of list at level one.

• nice. May be you explain a little for us newbies how this works :) Aug 28, 2014 at 2:15
• Michael, this made me realize that i could also use the pattern {___, Except[{}], ___} instead of the earlier contraption {___,{___,Except[{}],___},___}...
– kglr
Aug 28, 2014 at 2:40

Unless you have other requirements I recommend DeleteCases:

list = {{{1, 2}, {3}, {4, 5}}, {{6}, {}}, {{}, {}}};

DeleteCases[list, {{} ..}]

{{{1, 2}, {3}, {4, 5}}, {{6}, {}}}


For deletion at all levels you could use:

list /. {{} ..} -> Sequence[]

{{{1, 2}, {3}, {4, 5}}, {{6}, {}}}

• I don't think it will work for all levels. check this: {{{1, 2}, {3}, {4, 5, {5}}}, {{6}, {}, {}}, {{}, {{}, {}}}, {{}, {}, {2}}}; Aug 28, 2014 at 4:30
• @Algohi It does work on that list but it doesn't remove the new expression {{}} that is created. That is a different interpretation from what I intended. If you with to remove that you could use //. but be aware that it is inefficient. For greater efficiency one might use: Replace[list, {({} | _Sequence) ..} -> Sequence[], {1, -1}] Aug 28, 2014 at 6:07

that picks up all the elements of the outer list that have at least one non-empty list as an element.

I think Except is the logical choice and more functional also. But for fun, since Length[] applied to {{}} gives zero (after Flatten), may be this can be used to check

lis = {{{1, 2}, {3}, {4, 5}}, {{6}, {}}, {{}, {}}};
Cases[lis, x_ /; Length[Flatten@x] > 0]
(*  {{{1, 2}, {3}, {4, 5}}, {{6}, {}}} *)


Or can do direct compare to {} (after Flatten also)

lis = {{{1, 2}, {3}, {4, 5}}, {{6}, {}}, {{}, {}}};
Cases[lis, x_ /; Not[SameQ[Flatten@x, {}]]]
(* {{{1, 2}, {3}, {4, 5}}, {{6}, {}}} *)


another test

lis = {{{1, 2}, {3}, {4, 5}}, {{6}, {}}, {{}, {}}, {{}, {}, {2}}};
Cases[lis, x_ /; Not[SameQ[Flatten@x, {}]]]
(* {{{1, 2}, {3}, {4, 5}}, {{6}, {}}, {{}, {}, {2}}} *)


How a bout this for all levels:

lis = {{{1, 2}, {3}, {4,
5, {5}}}, {{6}, {}, {}}, {{}, {{}, {}}}, {{}, {}, {2}}};
Select[lis , #/# =!= # || # =!= # + # &] // Quiet
(* {{{1, 2}, {3}, {4, 5, {5}}}, {{6}, {}, {}}, {{}, {}, {2}}} *)