Возврат дубликатов в последовательности - PullRequest
10 голосов
/ 09 ноября 2011

Лучшее, что я мог придумать, было:

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

Есть ли более лаконичный способ?

Ответы [ 4 ]

17 голосов
/ 09 ноября 2011

Использовать понимание списка:

(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 голосов
/ 09 ноября 2011
(map key (remove (comp #{1} val) 
                 (frequencies seq)))
5 голосов
/ 31 марта 2016

Если вы хотите найти дубликаты на основе какого-либо свойства элементов в списке (т. Е. Это список карт или список записей / объектов 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))

выходы:

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

Если у вас есть список объектов Java, и вы хотите найти все объекты с повторяющимися именами:

(dups-with-function my-list #(.getFirstName %))
1 голос
/ 31 мая 2017

Минимальный фильтр и частоты oneliner, которые делают работу:

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

Однако он плохо работает с большими данными. Вам придется помочь компилятору, сказав:

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