所以我有一个问题的向量,并希望根据用户的输入递增并返回一个数字。它给了我麻烦,我认为这是因为缺乏对Clojure及其理想的理解。这是我得到的尽可能接近,但我得到的只是0。
(defn print-questions [questions]
(let [number 0]
(doseq [question questions]
(println question)
(let [x (read-line)]
(if (= (.toLowerCase x) "y")
(inc number)
(println "No"))))
number))
答案 0 :(得分:5)
Clojure不会像在命令式语言中那样使用变量,所以像(inc x)这样的语句会返回一个高于x的新值,而只留下x 而不是更改x。
编写此代码意味着:
(defn print-questions [questions]
(let [number 0]
;; start with zero every time
;; don't carry any information forward between iterations of the loop
(doseq [question questions]
(println question)
(let [x (read-line)]
(if (= (.toLowerCase x) "y")
(inc number) ;; this DOES NOT change the value in number
(println "No"))))
number)) ;; when you are all done, return the original value of number
这对于许多线程正在处理相同数据的情况非常有用,尽管它确实导致了一种看待事物的方式有所不同。
编写非常相似的东西的一种方法是循环遍历问题,同时将每个迭代的当前数值传递给下一个迭代,如下所示:
user=> (defn print-questions [questions]
#_=> (loop [number 0 remaining-questions questions]
#_=> (println remaining-questions)
#_=> (if (seq remaining-questions)
#_=> (let [x (read-line)]
#_=> (if (= x "y")
#_=> (do (println "yes")
#_=> (recur (inc number) (rest remaining-questions)))
#_=> (do (println "No")
#_=> (recur number (rest remaining-questions)))))
#_=> number)))
#'user/print-questions
user=> (print-questions ["who" "what" "when" "why"])
[who what when why]
y
yes
(what when why)
y
yes
(when why)
n
No
(why)
y
yes
()
3
哪个有效,虽然它有点冗长。相反,如果我们将这一问题看作是将问题集合减少到一个数字,其中每个减少阶段都会为结果添加一个零,它会更紧凑:
user=> (defn print-questions [questions]
#_=> (reduce (fn [answer question]
#_=> (println question)
#_=> (if (= "y" (read-line))
#_=> (inc answer)
#_=> answer))
#_=> 0
#_=> questions))
#'user/print-questions
user=> (print-questions ["who" "what" "when" "why"])
who
y
what
n
when
y
why
y
3
reduce需要一个函数来完成实际工作,一个值开始,以及一个inmputs列表。然后它使用具有第一个值的函数来创建新结果,然后使用具有第二个值的函数来生成新结果,然后使用第三个值,依此类推,直到输入中的每个值都有可能影响最终结果。