根据用户输入增加和返回数字

时间:2015-02-16 23:53:34

标签: loops clojure

所以我有一个问题的向量,并希望根据用户的输入递增并返回一个数字。它给了我麻烦,我认为这是因为缺乏对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))

1 个答案:

答案 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列表。然后它使用具有第一个值的函数来创建新结果,然后使用具有第二个值的函数来生成新结果,然后使用第三个值,依此类推,直到输入中的每个值都有可能影响最终结果。