Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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.

Thanks in advance for your help.

share|improve this question
    
Do you want to do like this. Cases[ {{{1, 2}, {3}, {4, 5}}, {{6}, {}}, {{}, {}}}, Except[{{}, {}}]] –  Junho Lee Aug 28 at 0:31

5 Answers 5

up vote 7 down vote accepted
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}, {}}} *)
share|improve this answer
    
Oh, wow! I didn't realize the solution would be that simple. Thank you very much. –  Shredderroy Aug 28 at 0:25
    
@Shredderroy, my pleasure. –  kguler Aug 28 at 0:35
    
@kguler so good ... –  eldo Aug 28 at 0:48
    
thank you @eldo... –  kguler Aug 28 at 0:49
2  
Cases[list, {___, {__}, ___}] seems simpler and faster. –  Michael E2 Aug 28 at 1:29

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.

share|improve this answer
    
nice. May be you explain a little for us newbies how this works :) –  Nasser Aug 28 at 2:15
    
Michael, this made me realize that i could also use the pattern {___, Except[{}], ___} instead of the earlier contraption {___,{___,Except[{}],___},___}... –  kguler Aug 28 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}, {}}}
share|improve this answer
    
I don't think it will work for all levels. check this: {{{1, 2}, {3}, {4, 5, {5}}}, {{6}, {}, {}}, {{}, {{}, {}}}, {{}, {}, {2}}}; –  Algohi Aug 28 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}] –  Mr.Wizard Aug 28 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}}} *)
share|improve this answer

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}}} *)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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