2015-02-16 2 views
1

Итак, у меня есть вектор вопросов и вы хотите увеличить и вернуть число на основе ввода пользователя. Это дает мне проблемы, и я полагаю, что это из-за отсутствия понимания 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

'(inc number)' больше напоминает 'number + 1'. Значение if похоже на '(x.toLowerCase(). Equals (" y ")? Число + 1: System.out.println (" Нет "))' – Sylwester

ответ

5

Clojure не использует переменные, как вы столкнулись в императивных языках, поэтому заявления типа (включая й) возвращает новое значение один выше чем 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 

уменьшить принимает функцию, чтобы сделать фактическую работу, значение для начала и список входов. Затем он использует эту функцию с первым значением для создания нового результата, затем использует функцию со вторым значением для получения нового результата, а третий и т. Д., Пока каждое значение на входе не сможет повлиять на конечный результат.

+0

Где же подходящее место для определения числа? –

+0

Я работаю над расширением ответа, чтобы описать другие способы обойти это. В этом случае это не вопрос определения числа в другом месте –

+0

Gotcha, спасибо, очень объяснительно! –

Смежные вопросы