我正在尝试在REPL中实现一个懒惰的序列(应该生成一个单独的字符串),没有运气。原始代码工作正常:
(def word_list ["alpha" "beta" "gamma" "beta" "alpha" "alpha" "beta" "beta" "beta"])
(def word_string (reduce str (interpose " " word_list)));
word_string ; "alpha beta gamma beta alpha alpha beta beta beta"
但是我不想单独留下足够好的东西,我想知道还有什么可行,并尝试删除reduce
,认为str
可能会产生同样的效果。它没有......
(def word_string (str (interpose " " word_list)))
word_string ; "clojure.lang.LazySeq@304a9790"
我尝试了显而易见的,再次使用reduce
,但这也无效。有another question关于实现看似有希望的懒惰序列,但我尝试过的任何工作都没有:
(reduce str word_string) ; "clojure.lang.LazySeq@304a9790"
(apply str word_string) ; "clojure.lang.LazySeq@304a9790"
(println word_string) ; "clojure.lang.LazySeq@304a9790"
(apply list word_string) ; [\c \l \o \j \u \r \e \. \l \a \n \g \. \L \a \z \y...]
(vec word_string) ; [\c \l \o \j \u \r \e \. \l \a \n \g \. \L \a \z \y...]
(apply list word_string) ; (\c \l \o \j \u \r \e \. \l \a \n \g \. \L \a \z \y...)
(take 100 word_string) ; (\c \l \o \j \u \r \e \. \l \a \n \g \. \L \a \z \y...)
事实上,某些变体,给了我“clojure.lang.LazySeq”中的字符也让我担心 - 我是否以某种方式丢失了实际的字符串值,而我的引用只是有价值“clojure.lang.LazySeq”?如果没有,我该如何实现价值?
澄清一下:鉴于word_string
被分配给一个懒惰的序列,我怎么能意识到它?像(realize word_string)
这样的东西,比如,如果存在的话。
更新:根据已接受的答案以及str
的工作原理,我发现可以获取实际的序列值,而不仅仅是其名称:
(reduce str "" word_string) ; "alpha beta gamma beta alpha alpha beta beta beta"
是的,这是可怕的代码。 :)我只是想了解发生了什么,为什么它会破坏,以及实际值是否仍然那里。
答案 0 :(得分:4)
你想要的是:
(def word_string (apply str (interpose " " word_list)))
查看str
的文档:
如果没有args,则返回空字符串。使用一个arg x,返回
x.toString()。 (str nil)返回空字符串。超过
一个arg,返回args的str值的串联。
所以你在序列上调用.toString
,生成该表示而不是将str
作为参数应用于序列的元素。
(clojure.string/join " " word_list)
此外,字符串不是惰性序列。 interpose
会返回一个懒惰的序列,而您正在调用.toString
。
答案 1 :(得分:1)
你不需要做任何特别的事情来实现clojure中的懒惰seq,你只需在seq预期的任何地方使用它。
user=> (def word-list ["alpha" "beta" "gamma" "beta" "alpha" "alpha" "beta" "beta" "beta"])
#'user/word-list
user=> (def should-be-a-seq (interpose " " word_list))
#'user/should-be-a-seq
user=> (class should-be-a-seq)
clojure.lang.LazySeq
所以我们有一个seq,如果我在任何情况下使用它来遍历seq中的所有值,它将最终完全实现。 e.g。
user=> (seq should-be-a-seq)
("alpha" " " "beta" " " "gamma" " " "beta" " " "alpha" " " "alpha" " " "beta" " " "beta" " " "beta")
它仍然是一个seq,实际上它仍然是以前的对象。
user=> (str should-be-a-seq)
"clojure.lang.LazySeq@304a9790"
正如Diego Basch所说,调用str就像调用.toString一样,对于LazySeq方法来说,它显然只是继承自Object的默认.toString。
因为它是一个seq,你可以像任何seq一样使用它,无论它是否已经完全实现。 e.g。
user=> (apply str should-be-a-seq)
"alpha beta gamma beta alpha alpha beta beta beta"
user=> (reduce str should-be-a-seq)
"alpha beta gamma beta alpha alpha beta beta beta"
user=> (str/join should-be-a-seq)
"alpha beta gamma beta alpha alpha beta beta beta"
user=> (str/join (map #(.toUpperCase %) should-be-a-seq))
"ALPHA BETA GAMMA BETA ALPHA ALPHA BETA BETA BETA"