2011-11-08 23 views
9

Najlepszym mogę wymyślić było:Wracając duplikatów w sekwencji

(defn dups [seq] 
    (map (fn [[id freq]] id) 
     (filter (fn [[id freq]] (> freq 1)) 
       (frequencies seq)))) 

Czy jest bardziej zwięzły sposób?

+0

Podoba mi się twoje rozwiązanie, ale po prostu zastąpi (fn [[id freq]] id) funkcją klucza. –

Odpowiedz

16

Użyj listowych:

(defn dups [seq] 
    (for [[id freq] (frequencies seq) ;; get the frequencies, destructure 
     :when (> freq 1)]   ;; this is the filter condition 
    id))        ;; just need the id, not the frequency 
11
(map key (remove (comp #{1} val) 
       (frequencies seq))) 
+0

Czy możesz wyjaśnić, co robi (comp # {1} val)? Thxs. –

+0

(comp # {1} val) zasadniczo oznacza (fn [x] (# {1} (val x))) - w zasadzie sprawdza, czy wartość argumentu wynosi 1 (jeśli jest zawarta w zestawie zawierającym liczbę 1). val tutaj to liczba w parze częstotliwości. –

4

Jeśli chcesz odnaleźć duplikaty oparte wyłączyć niektóre właściwości elementów na liście (czyli jest to lista mapy lub listy zapisów/Przedmioty java)

(defn dups-with-function 
    [seq f] 
    (->> seq 
     (group-by f) 
     ; filter out map entries where its value has only 1 item 
     (remove #(= 1 (count (val %)))))) 

(let [seq [{:attribute :one 
      :other-things :bob} 
      {:attribute :one 
      :other-things :smith} 
      {:attribute :two 
      :other-things :blah}]] 
    (dups-with-function seq :attribute)) 

wyjścia:

([:one 
    [{:attribute :one, :other-things :bob} 
    {:attribute :one, :other-things :smith}]]) 

Jeśli masz listę obiektów Java i chcesz znaleźć wszystkie te z duplikatów imion:

(dups-with-function my-list #(.getFirstName %)) 
0

filtr minimalny i częstotliwości oneliner że spełnia swoje zadanie:

(filter #(< 1 ((frequencies col) %)) col) 

jednak wykonuje źle na dużych danych. Będziesz musiał pomóc kompilatorowi, mówiąc: