#clojure #duplicates #sequence
#clojure #дубликаты #последовательность
Вопрос:
Лучшее, что я мог придумать, было:
(defn dups [seq]
(map (fn [[id freq]] id)
(filter (fn [[id freq]] (> freq 1))
(frequencies seq))))
Есть ли более краткий способ?
Комментарии:
1. Мне нравится ваше решение, но я бы просто заменил (fn [[id freq]] id) функцией key.
Ответ №1:
Используйте понимание списка:
(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
Ответ №2:
(map key (remove (comp #{1} val)
(frequencies seq)))
Комментарии:
1. Можете ли вы объяснить, что делает (comp #{1} val)? Спасибо.
2. (comp #{1} val) в основном означает (fn [x] (#{1} (значение x))) — в основном, он проверяет, равно ли значение аргумента 1 (если он содержится в наборе, содержащем число 1). значение здесь — это количество в паре частот.
Ответ №3:
Если вы хотите найти дубликаты на основе какого-либо свойства элементов в списке (т. Е. это список карт или список записей / объектов 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. Спасибо, что добавили свой ответ на мой вопрос: «Возврат дубликатов по клавише x в последовательности карт» 😉
Ответ №4:
Один элемент с минимальным фильтром и частотами, который выполняет работу:
(filter #(< 1 ((frequencies col) %)) col)
Однако он плохо работает с большими данными. Вам придется помочь компилятору, сказав:
(let [ freqs (frequencies col) ]
(filter #(< 1 (freqs %)) col))
Комментарии:
1. Не могли бы вы любезно объяснить, как / почему это помогает компилятору?
2. Помещая вычисление частот в предложение let лексического контекста, вы сначала принудительно вычисляете один раз, а не для каждого элемента в коллекции (можно надеяться, что компилятор сможет обнаружить и избежать).
Ответ №5:
some
является идеальной функцией для этого.
(defn dups [coll]
(some (fn [[k v]] (when (< 1 v) k))
(frequencies coll)))
Однако, по сути, это делает то же самое, что и понимание списка.