I have several strings:
(def a "some random string")
(def b "this is a text")
Now i want to concatenate parts of them to create a string “some text”. Unfortunately both of the strings below didn’t work.
(clojure.string/join " " [(take 4 a) (take-last 4 b)])
(str (take 4 a) " " (take-last 4 b))
It’s because functions take and take-last return lazy sequences. The question is: what is the proper way to concatenate multiple lazy sequences of strings and return one string?
Edit: I found one solution – (apply str (concat (take 4 a) " " (take-last 4 a))) – but is it the most correct way?
Rather than using sequence functions to slice the input strings, you might want to use the much more efficient
subs(for substring; note there’s a GC-related caveat about it, see below):The aforementioned caveat is that as long as the
"s"returned in the first example here remains ineligible for garbage collection, so does the original"asdf"(sincesubsreturns a “view” onto the inputStringwithout allocating fresh storage — this is the behaviour of Java’ssubstringmethod whichsubswraps). This is not a problem if you immediately hand the"s"off tosubsand retain no other reference to it, sincejoinwill discard it after pulling the characters.If you do end up working with lazy sequences of characters after all, there’s nothing to be done but to use something like
(map (partial apply str) [...your vector here...])to turn the inputs toclojure.string/joininto strings.