Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Please consider the following:

Split[data, patterns &]

How can I define patterns without typing &&Not[#=="char"] for every single pattern?

share|improve this question
up vote 5 down vote accepted

You can add some syntactic sugar to do that relatively easily. For example, define a head for that:

SplitPattern /: Split[expr_, SplitPattern[pt_]] :=
   Split[expr, MatchQ[#, pt] &];

And use this as follows:

lst = {"a", "b", "c", "d", "blabla", "e", "f"}

(*  {{a},{b},{c,d,blabla},{e,f}} *)

The performance may not be that great, but I guess the question was more about convenience.

share|improve this answer

It looks like you really want to use set of different dividers, in that case, you can simply test using a function that checks whether the current element is a member of your set of deviders:

 dividers = {3, 4, 5}
 Split[Range@10, ! MemberQ[dividers, #] &]

To answer your litteral question, your patterns is basically And taken over a range of structurally identical terms that are functions of a list of dividers, so you could use Map and Apply

patterns= Function[t, And @@ (Not[t == #] & /@ {"a", "b", "blabla"})]

Then you can use

lst = {"a", "b", "c", "d", "blabla", "e", "f"}
{{"a"}, {"b"}, {"c", "d", "blabla"}, {"e", "f"}}

In a similar fasion, if you just wanted to combine a seriues of different test you could use And@@{test1[#],test2[#],test3[#]}&.

I hope this helps.

share|improve this answer
I like your approach better from the perspective of comprehension. However, LeonidShifrins approach is faster. – John Dec 4 '12 at 16:33
@John One of the reasons why my code might be faster is that the patterns function here does not short-circuit: even when the very first pattern matches, it still goes on evaluating all others. – Leonid Shifrin Dec 4 '12 at 16:42

Another option is to create a temporary function which evaluates to False for your target strings and True otherwise.

splitAt[data_, x_] := Module[{f},
  (f[#, _] = False) & /@ x;
  f[__] = True;
  Split[data, f]]

lst = {"a", "b", "c", "d", "blabla", "e", "f"} ;
splitAt[lst, {"a", "b", "blabla"}]

(* {{"a"}, {"b"}, {"c", "d", "blabla"}, {"e", "f"}} *)
share|improve this answer

Your Answer


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.