/ / Retornando duplicatas em uma sequência - clojure, duplicates, sequence

Retornando duplicatas em uma sequência - clojure, duplicates, sequence

O melhor que pude pensar foi:

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

Existe uma forma mais concisa?

Respostas:

17 para resposta № 1

Use uma compreensão da lista:

(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

13 para resposta № 2
(map key (remove (comp #{1} val)
(frequencies seq)))

4 para resposta № 3

Se você gostaria de encontrar duplicatas com base em alguma propriedade dos itens na lista (ou seja, é uma lista de mapas ou uma lista de registros / objetos 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))

saídas:

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

Se você tiver uma lista de objetos java e quiser encontrar todos aqueles com nomes duplicados:

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

1 para resposta № 4

Filtro mínimo e frequências na linha que faz o trabalho:

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

No entanto, ele funciona mal com dados grandes. Você terá que ajudar o compilador dizendo:

(let [ freqs (frequencies col) ]
(filter #(< 1 (freqs %)) col))