2013-03-05 11 views

Odpowiedz

7

Clojure zapewnia wbudowany sposób na łatwe Java Interop.

(java.util.Collections/indexOfSubList '(a b c 5 6 :foo g h) '(5 6 :foo)) 
;=> 3 
+0

Dziękuję za odpowiedź. To właśnie wykorzystam na końcu, ale zwykle staram się unikać bezpośredniego wywoływania Java Interop z kodu "biznesowego", ponieważ uważam, że jest trochę gadatliwy. Dziękuję jednak. –

+0

Chociaż może to działać, należy pamiętać, że kolekcja nie jest sekwencją. – NielsK

+0

@NielsK Pojęcia filozoficzne na bok, myślę, że znajdziesz 'java.util.List' jako superklasę' seq' i że metoda java jest w parze 'java.util.List's. Jako takie, możesz użyć tego na leniwych sekwencjach (po prostu uważaj, aby nie ocenić nieskończonego) '(java.util.Collections/indexOfSubList (zakres 10) (zakres 3 7)); => 3', wektory, posortowane- mapy itp. –

3

Sekwencja to abstrakcja, a nie konkrecja. Pewne konkrecje, które można wykorzystać poprzez abstrakcję sekwencji, mogą znaleźć pozycję podciągu (na przykład łańcuchy i kolekcje java), ale sekwencje w ogóle tego nie robią, ponieważ ukryta konkrecja nie musi mieć indeksu .

Co jednak można zrobić, to stworzyć zestaw tożsamości elementu i funkcji indeksu. Spójrz na map-indexed.

Oto naiwna implementacja, która leniwie znajdzie pozycję (wszystkich) podciągów w sekwencji. Wystarczy użyć najpierw zabrać 1 lub tylko jednego, aby znaleźć:

(defn find-pos 
    [sq sub] 
    (->> 
    (partition (count sub) 1 sq) 
    (map-indexed vector) 
    (filter #(= (second %) sub)) 
    (map first))) 

=> (find-pos [:a :b \c 5 6 :foo \g :h] 
       [\c 5 6 :foo]) 
(2) 

=> (find-pos "the quick brown fox" 
       (seq "quick")) 
(4) 

zadbać, algorytmy indeksów opartych na ogół nie są czymś byś zrobił w języku funkcjonalnym. O ile nie istnieją dobre powody, dla których potrzebny jest indeks w ostatecznym wyniku, rozległe użycie wyszukiwania indeksu jest uznawane za zapach kodu.