【问题标题】:Clojure: idiomatic code for frequency mapClojure:频率图的惯用代码
【发布时间】:2013-09-08 18:42:34
【问题描述】:

让我们制作频率图:

(reduce #(update-in %1 [%2] (fnil inc 0)) {} ["a" "b" "a" "c" "c" "a"])

我担心的是 lambda #(...) 中的表达式 - 这是规范的做法吗?我可以做得更好/更短吗?

编辑:我发现的另一种方式:

(reduce #(assoc %1 %2 (inc %1 %2 0)) {} ["a" "b" "a" "c" "c" "a"])

看起来非常相似,优缺点是什么?性能?

【问题讨论】:

  • 你的第二个例子实际上是如何工作的?您将收到 clojure.lang.ArityException,因为将 3 个参数传递给 (inc)。

标签: clojure


【解决方案1】:

从 Clojure 1.2 开始,clojure.core 中有一个 frequencies 函数:

user=> (doc frequencies)
-------------------------
clojure.core/frequencies
([coll])
  Returns a map from distinct items in coll to the number of times
  they appear.

例子:

user=> (frequencies ["a" "b" "a" "c" "c" "a"])
{"a" 3, "b" 1, "c" 2}

恰好使用瞬态和三进制get;有关代码,请参见 (source frequencies),该代码在具有高度性能意识的同时非常惯用。

【讨论】:

    【解决方案2】:

    没有必要使用update-in。我的方法是:

    (defn frequencies [coll]
      (reduce (fn [m e]
                  (assoc m e (inc (m e 0))))
              {} coll))
    

    更新:我假设你知道 frequencies 也是核心,这只是一个练习。

    我不久前做了一个客座讲座,我在其中解释了如何逐步获得这个解决方案。对您来说不会是什么新鲜事,因为您已经接近 core 解决方案,但也许它对阅读此问题的其他人很有价值。幻灯片是荷兰语的。如果将 .html 更改为 .org 则更容易获得源代码:

    http://michielborkent.nl/gastcollege-han-20-06-2013/gastcollege.html http://michielborkent.nl/gastcollege-han-20-06-2013/gastcollege.org

    【讨论】:

      【解决方案3】:

      另一种仅使用“关联”和递归的方法:

      (defn my-frequencies-helper [freqs a-seq]
        (if (empty? a-seq)
          freqs
          (let [fst (first a-seq)
                new_set (if (contains? freqs fst)
                          (assoc freqs fst (inc (get freqs fst)))
                          (assoc freqs fst 1))]
            (my-frequencies-helper new_set (rest a-seq)))))
      
      (defn my-frequencies [a-seq]
        (my-frequencies-helper {} a-seq))
      

      (我的频率 [1 1 2 2 :D :D :D])

      => {1 2, 2 2, :D 3}

      (我的频率 [:a "moi" :a "moi" "moi" :a 1])

      => {:a 3, "moi" 3, 1 1}

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-20
        • 2013-10-29
        • 2016-03-17
        • 1970-01-01
        相关资源
        最近更新 更多