najprostszych (ale nie najbardziej FP-owski) jest niemal identyczny do przykładu:
(let [v [1 2 3 4 5 6 7]]
(doseq [i (range (count v))
j (range (inc i) (count v))]
(println (v i) (v j))))
i tutaj jest bardziej funkcjonalny wariant, aby wygenerować te wszystkie pary (to nie jest oparte na długość lub wskaźniki, ale raczej na iteracji ogona)
(let [v [1 2 3 4 5 6 7]]
(mapcat #(map (partial vector (first %)) (rest %))
(take-while not-empty (iterate rest v))))
Wydajność:
([1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [2 3] [2 4]
[2 5] [2 6] [2 7] [3 4] [3 5] [3 6] [3 7] [4 5]
[4 6] [4 7] [5 6] [5 7] [6 7])
potem po prostu korzystać z tych par w doseq
jakiegokolwiek skutku ubocznego:
(let [v [1 2 3 4 5 6 7]
pairs (fn [items-seq]
(mapcat #(map (partial vector (first %)) (rest %))
(take-while not-empty (iterate rest items-seq))))]
(doseq [[i1 i2] (pairs v)] (println i1 i2)))
zmiana: następującą odpowiedź @ dg123 za. to jest ładne, ale można zrobić to nawet lepiej, używając doseq
funkcje 's i for
Like rozpad i osłony:
(let [v [1 2 3 4 5 6 7]]
(doseq [[x & xs] (iterate rest v)
:while xs
y xs]
(println "x:" x "y:" y)))
iterację ogonów kolekcji, ale należy pamiętać, że iterate
produkuje nieskończona coll:
user> (take 10 (iterate rest [1 2 3 4 5 6 7]))
([1 2 3 4 5 6 7] (2 3 4 5 6 7) (3 4 5 6 7)
(4 5 6 7) (5 6 7) (6 7) (7)()()())
, więc musisz go w jakiś sposób ograniczyć, aby uwzględnić tylko puste kolekcje. postać rozpad [x & xs]
rozdziela argumentu pierwszego param i sekwencję params spoczynku:
user> (let [[x & xs] [1 2 3 4 5 6]]
(println x xs))
1 (2 3 4 5 6)
nil
i gdy oprawiony zbiór pusty, posiada jeden elemencie, xs
będzie nil
:
user> (let [[x & xs] [1]]
(println x xs))
1 nil
nil
więc po prostu skorzystaj z tej funkcji, korzystając ze straży :while
w zrozumieniu listy.
w końcu po prostu skonstruować pary (czy jakiś efekt uboczny w tym przypadku) dla x
i każdy element w xs
Jak już wspomniano, 'doseq' jest sposobem. Ale kiedy chcesz manipulować danymi, prawdopodobnie szukasz 'map' lub' for'. – user5187212