On 16 February 2011 10:01, Michael Sanders <[email protected]> wrote:
> I think I've worked out a better solution (hope this post renders properly):
>
> (ns topic (require [clojure.string :as s]))
>
> (defn load-block
>
> "TOPIC database: prints associated blocks to stdout"
>
> ([tag]
> (let [STATE (atom 0)
> rx (re-pattern (str "(?i)" tag "[[:space:]]*(,|$)"))]
> (loop [line (read-line)]
> (when line
> (when (and (not= "" (s/trim line))
> (not= "\t" (subs line 0 1)))
> (if (re-find rx line)
> (reset! STATE 1)
> (reset! STATE 0)))
> (if (= @STATE 1)
> (println line))
> (recur (read-line)))))))
This is better than using defs, but it's still not very idiomatic.
Start by factoring out the bit that updates the state:
(defn update-state [state line]
(if (or (s/blank? line) (.startsWith line "\t"))
state
(if (re-find rx line)
:print
:skip))
Then in the looping logic, pass the state through the loop/recur:
(loop [state :skip]
(when-let [line (read-line)]
(let [state (update-state state line)]
(when (= state :print) (println line))
(recur state))))
There are probably more functional ways of doing this (e.g. using
line-seq and reduce), but this a step in the right direction.
- James
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en