2010-07-11 4 views
4

Je suis coincé dans une boucle Clojure et j'ai besoin d'aide pour sortir.Coincé dans une boucle Clojure, besoin de conseils

Je veux d'abord définir un vecteur

(def lawl [1 2 3 4 5]) 

je

(get lawl 0) 

et obtenir "1" en retour. Maintenant, je veux une boucle qui se chaque numéro dans le vecteur, donc je fais:

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

Dans mon esprit, ce qui est censé définir la valeur de i à zéro, alors si i est plus bas que le nombre de vecteur de loi, il devrait obtenir chaque valeur de loi, puis augmenter la variable i avec 1 et essayer à nouveau, en obtenant la prochaine valeur dans le vecteur.

Cependant, cela ne fonctionne pas et j'ai passé du temps à essayer de le faire fonctionner et sont totalement bloqués, j'apprécierais de l'aide. J'ai également essayé de changer "si" en "quand" avec le même résultat, il ne fournit aucune donnée, le REPL entre simplement une nouvelle ligne et clignote.

EDIT: Correction de la récurrence.

Répondre

7

Vous devez considérer ce qui est « d'obtenir chaque valeur lawl » censé signifier. Votre appel get "obtient" en effet la valeur appropriée, mais puisque vous ne faites jamais rien avec, il est simplement rejeté; Bozhidar suggestion d'ajouter un println est un bon et vous permettra de voir que la boucle a effectivement accès à tous les éléments de lawl (il suffit de remplacer (get ...) par (println (get ...)), après avoir fixé la (inc) =>(inc i) chose Bozhidar mentionné aussi). Cela dit, si vous voulez simplement faire quelque chose avec chaque chiffre, loop/recur n'est pas un bon moyen d'y parvenir. Voici quelques autres:

;;; 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)) 

Ce n'est que le début. Pour une bonne visite de la bibliothèque standard de Clojure, voir l'article Clojure -- Functional Programming for the JVM de Mark Volkmann.

+0

Si vous remplacez 'inc' par, disons,' produire-html' dans les exemples 'map', vous obtiendrez probablement le meilleur ajustement pour votre cas d'utilisation. –

+0

Wow, doseq était tout ce dont j'avais besoin! – bleakgadfly

3

(recur (inc)) devrait être (recur (inc i))

Même si ce code sera juste retour 1 à la fin, si vous voulez une liste du numéro que vous pouvez ajouter une expression d'impression :-) boucles index à base BTW ne sont pas nécessaires à tous les dans des scénarios comme celui-ci.

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

Le problème est que j'ai un vecteur externe dont j'ai besoin que chaque valeur soit "poussée" vers une fonction. L'exemple que j'ai utilisé ci-dessus est juste un moyen de montrer comment j'essaie de faire passer chaque valeur du vecteur "lawl" dans la fonction "get". J'ai une fonction qui génère une sortie HTML, et j'ai une fonction qui lit un fichier et l'envoie à la fonction HTML pour la génération. J'ai créé une fonction qui place chaque fichier dans un répertoire donné dans un vecteur, donc j'essaye de faire une boucle qui pousse chaque fichier dans la fonction. – bleakgadfly

+0

Disons que j'ai le vecteur "dirs" qui contient ["/ home/bozhidar/file1" "/ home/bozhidar/file"] Je veux une boucle qui envoie chacun de ces fichiers à une fonction. Ce que ferait une boucle forcée en C ou en Python. – bleakgadfly

+2

Vous devez vous demander ce que signifie l'envoi d'un fichier à votre fonction pour vous. Si vous avez une fonction qui prend un nom de fichier et * renvoie * du HTML, vous voudrez faire '(map produce-html les-fichiers)' (où 'the-files' peut être n'importe quel seqable, en particulier un vecteur) .Si vous avez une fonction qui prend un nom de fichier et * provoque un effet secondaire impliquant le HTML *, vous voudrez faire quelque chose comme '((doseq [f les-fichiers] (print-html f))'. –

Questions connexes