I've defined the following 3 functions using the leiningen REPL:
(defn rand-int-range [floor ceiling] (+ floor (rand-int (- ceiling floor))))
(defn mutate-index
"mutates one index in an array of char and returns the new mutated array"
[source idx]
(map
#(if (= %1 idx)
(char (+ (int %2) (rand-int-range -3 3)))
%2)
(iterate inc 0)
source))
(defn mutate-string
[source]
(str
(mutate-index
(.toCharArray source)
(rand-int (alength (.toCharArray source))))))
When I run (mutate-string "hello")
, instead of the REPL printing out the mutated string, it is printing out clojure.lang.LazySeq@xxxxxx where the 'xxxxx' is a random sequence of numbers and letters. I would expect it to instead print something like "hellm" Is this really giving me a string back like I think? If it is, how can I get the REPL to show me that string?
1) To convert a sequence of characters (which is what mutate-index
returns) to a string, use apply str
rather than just str
. The latter operates on objects, not sequences.
(str [\a \b \c])
=> "[\\a \\b \\c]"
(apply str [\a \b \c])
=> "abc"
2) Strings are seqable, meaning you can use sequence functions like map
and filter
on them directly without stuff like .toCharArray
.
3) Consider using map-indexed
or StringBuilder
to accomplish what you're trying to do:
(apply str (map-indexed (fn [i c] (if (= 3 i) \X c)) "foobar"))
=> "fooXar"
(str (doto (StringBuilder. "foobar") (.setCharAt 3 \X)))
=> "fooXar"
That happens, because the map function returns a lazy sequence, which string reprsentation is just the class name and a hash (clojure.lang.LazySeq@xxxxxx).
In order to get the original working you need to first to get the lazy sequence evaluated. By using the (apply str ...) like Justin adviced that should happen and you should get the correct result.
Otherwise normally if you see similar problems due to not evaluating a lazy sequence you should try out function doall, which forces the evalutation of a lazy sequence
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With