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.

Please consider the following:

Split[data, patterns &]
patterns=Not[#=="a"]&&Not[#=="b"]&&...&&Not[#=="blabla"];

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

share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

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

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

And use this as follows:

lst = {"a", "b", "c", "d", "blabla", "e", "f"}
Split[lst,SplitPattern[Except["a"|"b"|"blabla"]]]

(*  {{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
add comment

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"}
Split[lst,patterns]
{{"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
add comment

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
add comment

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.