我使用leiningen REPL定义了以下3个函数:
(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))))))
当我运行(mutate-string "hello")
时,不是REPL打印出变异的字符串,而是打印出clojure.lang.LazySeq@xxxxxx,其中'xxxxx'是一个随机的数字和字母序列。我希望它能打印出像“hellm”这样的东西吗?这真的像我想的那样给了我一个字符串吗?如果是,我如何让REPL向我显示该字符串?
答案 0 :(得分:17)
1)要将字符序列(mutate-index
返回的内容)转换为字符串,请使用apply str
而不是str
。后者对物体而不是序列进行操作。
(str [\a \b \c])
=> "[\\a \\b \\c]"
(apply str [\a \b \c])
=> "abc"
2)字符串是可选的,这意味着您可以直接使用map
和filter
之类的序列函数,而不需要.toCharArray
之类的字符。
3)考虑使用map-indexed
或StringBuilder
来完成您要执行的操作:
(apply str (map-indexed (fn [i c] (if (= 3 i) \X c)) "foobar"))
=> "fooXar"
(str (doto (StringBuilder. "foobar") (.setCharAt 3 \X)))
=> "fooXar"
答案 1 :(得分:8)
这种情况发生了,因为map函数返回一个惰性序列,该字符串reprsentation只是类名和散列(clojure.lang.LazySeq@xxxxxx)。
为了获得原始工作,您需要首先评估延迟序列。通过使用(应用str ...),Justin建议应该发生,你应该得到正确的结果。
否则通常如果由于未评估惰性序列而发现类似问题,则应尝试使用函数doall,这会强制评估惰性序列
答案 2 :(得分:0)
每当我想获得一个懒惰序列的字符串值时,我就会使用clojure.core/pr-str
:
user=> (clojure.tools.logging/infof "This is a lazy seq [%s]" (take 5 (range 100)))
INFO user - This is a lazy seq [clojure.lang.LazySeq@1b554e1]
nil
user=> (clojure.tools.logging/infof "This is a lazy seq [%s]" (pr-str (take 5 (range 100))))
INFO user - This is a lazy seq [(0 1 2 3 4)]
nil