On Mon, May 30, 2011 at 6:15 PM, iz bash <killernemesisbl...@gmail.com> wrote: > so clojures like my first programming language. most of the time > now ,i use map /reduce/.. with lazy sequences but sometimes i just > cant seem to find a solution other than using loop-recur. then i read > somewhere almost all loop recur situations can be translated into > reduce. so ive posted a function below...how'd you implement it using > only higher order functions? > > > (defn rem-dup [stri] > (loop [[x y & z] (seq stri) ,bui []] > (cond (nil? x) bui > (= x y \space) (recur (cons y z) bui) > :else (recur (cons y z) (conj bui x)))))
Any loop/recur can be trivially turned into a use of iterate: (defn rem-dup-iter [stri] (first (first (drop-while (comp nil? first) (iterate (fn [[_ [x y & z] bui]] (cond (nil? x) [bui nil nil] (= x y \space) [nil (cons y z) bui] :else [nil (cons y z) (conj bui x)])) [nil (seq stri) []]))))) but I'm guessing you want more. Loops that grow a collection and add to it can generally be turned into map, for, or reduce expression. Here's your loop as a map call: (defn rem-dup-map [stri] (let [stri (seq (concat stri [(char 0)]))] (filter identity (map (fn [x y] (if-not (= x y \space) x)) stri (next stri))))) It relies, in its use of "filter identity", on strings never containing nil as a character. In other circumstances you might need to use a dedicated sentinel value guaranteed to be unique, e.g. (let [sentinel (Object.)] (remove #{sentinel} (map ... (if ... foo sentinel)))). It also appends a NUL to the end of the string because otherwise the map will stop one character short of the end. As a for loop: (defn rem-dup-for [stri] (for [[x y] (partition 2 1 [] stri) :when (not= x y \space)] x)) Short and sweet! As a reduce: (defn rem-dup-reduce [stri] (reduce (fn [bui [x y]] (if (= x y \space) bui (conj bui x))) [] (partition 2 1 [] stri))) Last, but not least, if none of the above seem to be workable and you want it to be lazy (the iterate, map, and for versions above are lazy, while the loop and reduce versions are not), you might resort to direct use of the lazy-seq macro: (defn rem-dup-lazy-seq [stri] (lazy-seq (let [[x y & z] stri] (if x (if (= x y \space) (rem-dup-lazy-seq (cons y z)) (cons x (rem-dup-lazy-seq (cons y z)))))))) -- Protege: What is this seething mass of parentheses?! Master: Your father's Lisp REPL. This is the language of a true hacker. Not as clumsy or random as C++; a language for a more civilized age. -- 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