Is there an idiomatic way to build up a string over different lines of
code? Or, should one simply use StringBuilder.
> I would just use (str) - it uses a StringBuilder when given more than one argument:
There's also (format), which I find helpful for building more complex strings.
> What if you are appending over different lines of code?
Could you give an example of what you're trying to do? Mutable strings are almost never necessary, in my experience.
str uses a string builder behind the scenes, so it's efficient this
way. If you keep applying str at each point in your code, it won't
be.
I'm trying to think what your code would look like that you'd have
multiple 'lines' computing pieces that you are assembling into a
string section at a time...?
If you're accumulating things that you want to turn into a string
later, you could always put the pieces into a vector and then do:
(apply str vector-of-pieces)
--
Sean A Corfield -- (904) 302-SEAN
Railo Technologies, Inc. -- http://getrailo.com/
An Architect's View -- http://corfield.org/
"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood
Is there an idiomatic way to build up a string over different lines of
code? Or, should one simply use StringBuilder.
> str uses a string builder behind the scenes, so it's efficient this
> way.
If the `str' implementation didn't take the input sequence to be lazy,
it could figure out how long the resulting string needed to be, and
construct the StringBuilder using the single-integer constructor,
ensuring that no reallocation and copying occurs. Some temporary
allocation would still be necessary to hold the Object-to-String
projection, as `str' calls Object#toString() on each argument, rather
than assuming the arguments are already of type String.
--
Steven E. Harris
> (ns test-test.parse
> (:use [clojure.contrib.string :only (split)]))
>
> (defn parse-char [m c]
> (condp = (:state m)
> :degree (cond
> (Character/isDigit c) (assoc m :degree (+ (* (:degree
> m) 10) (Character/digit c 10)))
> (Character/isWhitespace c) (assoc
> m :state :whitespace :buf (conj (:buf m) (:degree m) " ") :degree 0))
> :whitespace (cond
> (Character/isDigit c) (assoc
> m :state :degree :degree (+ (* (:degree m) 10) (Character/digit c
> 10)))
> (Character/isWhitespace c) m)))
>
> (defn parse [s]
> (let [m (reduce parse-char {:state :degree :degree 0 :buf []} (str s
> " "))]
> (apply str (:buf m))))
>
> (println (parse "1 2 33"))
One minor improvement would be to use clojure.string/join instead of str. That way you won't have to manually append a space after each number in :buf (nor use apply).