2012-04-05 12 views
11

Il clojure ha un potente "ciclo" simile a una comune lisc.Ottieni due elementi da una sequenza ogni volta

ad esempio:

ottenere due elementi da una sequenza ogni volta

Common Lisp:

(loop for (a b) on '(1 2 3 4) by #'cddr collect (cons a b)) 

come fare questo in Clojure?

+1

È possibile implementare CL in clojure ... –

+0

Si prega di definire "potente". –

risposta

13

Sfruttando for e alcuni destrutturazione si può raggiungere il tuo esempio specifico:

(for [[a b] (partition 2 [1 2 3 4])](use-a-and-b a b)) 
+0

Si noti che 'for' non è un costrutto di loop, ma una lista di comprensione, che produce un pigro seq di risultati. Inoltre, contrariamente al Common LISP, è difficile farlo funzionare molto bene. –

+0

@Marko - hai esempi specifici? – sw1nn

+0

Non capisco - esempi di cosa esattamente? –

2

di Clojure polivalente loop costrutto è for. Non ha tante funzioni quante sono integrate in CL loop (specialmente non quelle a effetto collaterale, dal momento che Clojure incoraggia la purezza funzionale), così tante operazioni che potresti altrimenti fare semplicemente con lo loop sono "intorno" allo for. Ad esempio, per sommare gli elementi generati da for, si dovrebbe mettere un apply + di fronte ad esso; per camminare gli elementi a coppie, si dovrebbe (come mostra sw1nn) utilizzare partition 2 sulla sequenza di input alimentata in for.

1

Lo farei con loop, recur e destrutturare.

Ad esempio, se volevo gruppo ogni due valori insieme:

(loop [[a b & rest] [1 2 3 4 5 6] 
     result []] 
    (if (empty? rest) 
    (conj result [a b]) 
    (recur rest (conj result [a b])))) 

finisce con un risultato di:

=> [[1 2] [3 4] [5 6]]

a e b sono i primi e secondi elementi di la sequenza, rispettivamente, e quindi rest è ciò che rimane. Possiamo quindi ricorrere in modo ricorrente fino a quando non è rimasto nulla in rest e abbiamo finito.

Problemi correlati