There's also re-split in str-utils in clojure.contrib; (use 'clojure.contrib.str-utils) (re-split #"\s" "The quick brown fox") => ("The" "quick" "brown" "fox")
You can then use all the good clojure collection functions; (def words (re-split #"\s" "The quick brown fox")) (some #{"brown"} words) => "brown" (some #{"foo"} words) => nil (nth words 2) => "brown" (str-join "," words) => "The,quick,brown,fox" ..., etc. (There's also some good stuff in str-utils2 worth looking at). The "some" function above needs some explanation; It takes a predicate, applies it to each element of the collection and returns the first logical true (not nil) value if found otherwise nil. The #{"brown"} is a set containing "brown", but sets, like maps are a function of their elements, e.g; (#{"a" "b"} "b") => "b" and hence acts as a predicate for testing each element in words in the some function. There are also endless things you can do with map and reduce; (map (fn [w] (.toUpperCase w)) words) => ("THE" "QUICK" "BROWN" "FOX") same as; (map #(.toUpperCase %) words) => ("THE" "QUICK" "BROWN" "FOX") Say you wanted to encode a "record" of stems from a map of word/stem's; (let [stems {"the" :th "quick" :qk "brown" :br "fox" :fx}] (reduce (fn [rec x] (conj rec (stems (.toLowerCase x)))) [] words)) => [:th :qk :br :fx] So then given that background and that you're looking for a clojure approach rather than a specific solution to your "brown" split example, lets elaborate on a possible approach; You could "abstract" the requirement to something like; "Given a collection and a predicate to find an element in that collection, return two collections - up to the split element and the remaining elements (including the split element)." (defn split-coll "Doc as above." [coll pred] (reduce (fn [[l r] x] (if-not (empty? r) [l (conj r x)] (if (pred x) [l [x]] [(conj l x) r]))) [[][]] coll)) (split-coll '(:a :b :c) #(= % :b)) => [:a] [:b :c]] (split-coll '(:a :b :c) #(= % :x)) => [[:a :b :c] []] (split-coll '(:a :b :c) #(= % :a)) => [[] [:a :b :c]] and of course; (split-coll words #(= % "brown")) => [["The" "quick"] ["brown" "fox"]] finally, you could create the specific sentence function; (defn split-sentence [sentence word] (split-coll (re-split #"\s" sentence) #{word})) (split-sentence "The quick brown fox" "brown") => [["The" "quick"] ["brown" "fox"]] and you can also use de-structuring to get exactly what you were originally looking for; (let [[l r] (split-sentence "The quick brown fox" "brown")] r) => ["brown" "fox"] To explain the above reduce function ; we start with two empty vectors in a vector [[][]] and then looping through the collection on each iteration that vector is passed to the fn as the first arg. We de-structure that into l and r for the left and right vectors. If r is not empty we've already found the element, so conj x into the r vector. Otherwise if x satisfies the pred, conj it to the r vector, else we haven't got there yet, so conj it to the l vector. For completeness, I should show a loop/recur alternative as this is a totally idiomatic clojure technique, but should be used for functional goals, not just trying to emulate imperative ways. (defn split-coll [coll pred] (loop [c coll [l r] [[][]]] (if (nil? (seq c)) [l r] (recur (next c) (let [x (first c)] (if (nil? c) [l r] (if-not (empty? r) [l (conj r x)] (if (pred x) [l [x]] [(conj l x) r])))))))) (split-coll words #(= % "brown")) => [["The" "quick"] ["brown" "fox"]] It is also important to master loop/recur as you can use this more easily than reduce for complex looping constructs, nested loops, performant techniques, etc. I hope that gives you a feel of the kinds of things you can do with functional idioms and clojure and also a general approach to functional programming. Takes a while to pickup all these tips but you'll never look back. Rgds, Adrian. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---