如何使用clojure查找列表中出现多次的数字

时间:2017-01-16 18:06:35

标签: clojure

我有一个数字列表2 4 3 7 4 9 8 5 12 24 8.

我需要找到在clojure中重复多次的数字。

我使用了frequencies函数来查找。但结果是

{2 1,4 2,3 1,7 1,9 1,8 2,5 1,12 1,24 1}

我最初想到将它们视为key value,然后将每个键值取一次,看看val是否为> 1.如果值大于1,那么我需要加1。

但我无法解决这个问题。

任何人都可以帮助我吗?

无论如何,我可以将它变成[[2 1][4 2][3 1][7 1][9 1][8 2][5 1][12 1][24 1]]并递归地考虑每个向量或者你能想到更好的想法。

谢谢。

5 个答案:

答案 0 :(得分:1)

如果您想要重复的项目:

(defn repeated [coll]
  (->> coll
       frequencies
       (remove #(= 1 (val %)))
       keys))

(repeated [2 4 3 7 4 9 8 5 12 24 8])
;(4 8)

如果你只想数数:

(defn repeat-count [coll]
  (->> coll
       frequencies
       (remove #(= 1 (val %)))
       count))

(repeat-count [2 4 3 7 4 9 8 5 12 24 8])
;2

你可以懒惰地这样做,这样它就会以无穷无尽的顺序发挥作用:

(defn repeated [coll]
  ((fn ff [seen xs]
     (lazy-seq
      (when-let [[y & ys] (seq xs)]
        (case (seen y)
         ::several (ff seen ys)
         ::once (cons y (ff (assoc seen y ::several) ys))
         (ff (assoc seen y ::once) ys)))))
   {} coll))

(repeated [2 4 3 7 4 9 8 5 12 24 8])
;(4 8)

这类似于核心distinct

......最后,为了简洁起见,......

(defn repeated [coll]
  (for [[k v] (frequencies coll) :when (not= v 1)] k))

我从Piotrek Byzdyl's answer偷走了keys的使用。它只应用于地图。但在这里的一系列地图条目上工作得非常好。

答案 1 :(得分:1)

以下功能将继续在您停留的地方继续:

(defn find-duplicates [numbers]
  (->> numbers
       (frequencies)
       (filter (fn [[k v]] (> v 1)))
       (keys)))

它将过滤值大于1的地图条目,然后提取其键。

(find-duplicates [2 4 3 7 4 9 8 5 12 24 8])
;; => (4 8)

答案 2 :(得分:1)

(->> s (group-by identity) (filter (comp next val)) keys)

答案 3 :(得分:0)

你走在正确的轨道上。

如果你seq over hash-map,e。 G。通过map,你得到你描述的kv元组结构,并且可以在元素转换函数中构造一个单独的元组:

(->> s
     (frequencies)
     (map (fn [[number times]]
            (cond-> number           ; take number
              (> times 1) (inc)))))  ; inc if (times > 1), otherwise return number

答案 4 :(得分:0)

您可以使用此方法。

(def c [2 4 3 7 4 9 8 5 12 24 8])

(->> c
     sort
     (partition-by identity)
     (filter #(> (count %) 1))
     (map first))