Застрял в цикле Clojure, нужно некоторое руководство - PullRequest
4 голосов
/ 11 июля 2010

Я застрял в цикле Clojure и мне нужна помощь, чтобы выйти.

Сначала я хочу определить вектор

(def lawl [1 2 3 4 5])

Я делаю

(get lawl 0)

И получить «1» в ответ.Теперь я хочу цикл, который получает каждое число в векторе, поэтому я делаю:

(loop [i 0]
   (if (< i (count lawl)) 
     (get lawl i) 
       (recur (inc i))))

На мой взгляд, это должно установить значение i на ноль, тогда, если я ниже, чем количествовектора закона, он должен получить каждое значение закона, а затем увеличить переменную i на 1 и повторить попытку, получив следующее значение в векторе.

Однако это не работает, и я потратил некоторое время на попыткичтобы заставить его работать и полностью застрял, был бы признателен за некоторую помощь.Я также пытался изменить «если» на «когда» с тем же результатом, он не предоставляет никаких данных, когда REPL просто входит в новую строку и мигает.

РЕДАКТИРОВАТЬ: исправил повторение.

Ответы [ 2 ]

7 голосов
/ 11 июля 2010

Вы должны рассмотреть, что означает «получить каждое значение lawl».Ваш get вызов действительно «получает» соответствующее значение, но, поскольку вы ничего с ним не делаете, он просто отбрасывается;Предложение Божидара добавить println является хорошим и позволит вам увидеть, что цикл действительно имеет доступ ко всем элементам lawl (просто замените (get ...) на (println (get ...)) после исправления (inc) =>(inc i) вещь, о которой говорил и Божидар).

Тем не менее, если вы просто хотите что-то делать с каждым числом по очереди, loop / recur - совсем не лучший способ сделать это.Вот некоторые другие:

;;; do some side-effecty thing to each number in turn:
(dotimes [i (count lawl)]
  (println (str i ": " (lawl i)))) ; you don't really need the get either

;; doseq is more general than dotimes, but doesn't give you equally immediate
;; acess to the index
(doseq [n lawl]
  (println n))

;;; transform the lawl vector somehow and return the result:
; produce a seq of the elements of lawl transformed by some function
(map inc lawl)
; or if you want the result to be a vector too...
(vec (map inc lawl))
; produce a seq of the even members of lawl multiplied by 3
(for [n lawl
      :when (even? n)]
  (* n 3))

Это только начало.Хороший обзор стандартной библиотеки Clojure см. В статье Clojure - Функциональное программирование для JVM , написанной Марком Фолькманном.

3 голосов
/ 11 июля 2010

(recur (inc)) должно быть (recur (inc i))

Даже в этом случае этот код будет просто возвращать 1 в конце, если вы хотите получить список чисел, вы можете добавить выражение для печати :-) Между прочим, циклы на основе индекса вообще не нужны в таких сценариях, как этот.

(loop [list [1 2 3 4 5] ]
         (if (empty? list)
             (println "done")
             (do
              (println (first list))
              (recur (rest list)))))
...