2012-04-05 14 views
11

Czy clojure ma potężną "pętlę", jak zwykłe seplenienie.Uzyskaj dwa elementy z sekwencji za każdym razem

na przykład:

dostać dwa elementy z sekwencji za każdym razem

Common Lisp:

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

jak to zrobić w Clojure?

+1

Można wdrożyć CL w clojure ... –

+0

Proszę zdefiniować "mocny". –

Odpowiedz

13

Wykorzystując for a niektóre demontażu struktury można osiągnąć swój konkretny przykład:

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

Zauważ, że 'for' nie jest konstrukcją pętli, ale zawiera zrozumienie listy, co daje leniwą sekcję wyników. Ponadto, w przeciwieństwie do wspólnego LISP-a, ciężko jest sprawić, by działał on wyjątkowo dobrze. –

+0

@Marko - czy masz konkretne przykłady? – sw1nn

+0

Nie rozumiem - przykłady czego dokładnie? –

2

Clojure jest wielofunkcyjny zapętlenie konstrukt jest for. Nie ma w nim wbudowanych tak wielu funkcji, jak wbudowana w CL CL-a (w szczególności te, które nie są efektem ubocznym, ponieważ Clojure zachęca do funkcjonalnej czystości), więc wiele operacji, które można wykonać w inny sposób, po prostu za pomocą samego loop, jest wykonywanych "w pobliżu" for. Na przykład, aby zsumować elementy wygenerowane przez for, należy umieścić przed nim apply +; aby przejść elementy parami, możesz (jak pokazuje sw1nn) użyć partition 2 na sekwencji wejściowej podanej do for.

1

Zrobiłbym to z loop, recur i zniszczeniem.

Na przykład, jeśli chciałem grupy co dwie wartości ze sobą:

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

kończy się w wyniku:

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

a i b są pierwsze i drugie elementy sekwencja odpowiednio, a następnie rest jest to, co zostało. Możemy wtedy powtarzalnie chodzić, dopóki nie pozostanie nic w rest i skończymy.

Powiązane problemy