【问题标题】:Clojure basics: counting frequenciesClojure 基础知识:计数频率
【发布时间】:2014-06-20 07:37:15
【问题描述】:

我正在学习Clojure,在网上看到了这段代码:

(count (filter #{42} coll))

如前所述,它确实计算 coll 中数字 42 的出现次数。 #{42} 是一个函数吗?关于过滤器的 Clojure 文档说它应该是,因为 sn-p 像宣传的那样工作。我只是不知道它是如何工作的。如果有人可以为我澄清这一点,那就太好了。我自己对同一件事的解决方案是:

(count (filter #(= %1 42) coll))

为什么我的过滤函数有括号,而我在网上找到的sn-p在过滤函数周围有花括号(#(...) vs. #{...})?

【问题讨论】:

  • 你看到这个答案了吗? stackoverflow.com/questions/3249334/…
  • 不,我没有看到那个答案。我可以看到他们也在使用类似的代码。还提到(#{x} x) 返回x。我只是不明白#{x} 作为一个函数在做什么。不就是一套吗?
  • 看我的回答。集合不仅仅是一个集合——除此之外,它是一个 IFn,因此您可以将其视为一个函数。
  • 这是切线相关的,但如果你不知道,Clojure 还有一个名为frequencies 的函数,它对这种情况很有用。它生成集合中每个项目到其出现次数的映射。因此,您可以像这样执行上述操作:((frequencies coll) 42) -- (frequencies coll) 生成一个映射,该映射用作查找 42 并返回出现次数的函数。 (编辑:公平地说,这不是性能)

标签: clojure


【解决方案1】:
=> #{42}
#{42}

定义一个集合...

=> (type #{42})
clojure.lang.PersistentHashSet

=> (supers (type #{42}))
#{clojure.lang.IHashEq java.lang.Object clojure.lang.IFn ...}

有趣的是,该集合实现了 IFn,因此您可以将其视为一个函数。该函数的行为是“如果集合中存在此项,则返回它”。

=> (#{2 3} 3)
3
=> (#{2 3} 4)
nil

map 和 vector 等其他集合以类似的方式作为函数出现,根据需要通过键或索引检索。

=> ({:x 23 :y 26} :y)
26
=> ([5 7 9] 1)
7

甜,不是吗? :-)

【讨论】:

    【解决方案2】:

    是的,#{42} 是一个函数,

    • 因为它是一个集合,并且集合以及其他功能是 函数:它们实现了clojure.lang.IFn 接口。
    • 应用于集合中的任何值,它们返回它;适用于任何事物 否则,他们返回nil
    • 所以#{42} 测试它的参数是否是42(只有nilfalse 是假的,记住)。

    Clojure 的方法是让一切都成为一个有用的函数:

    • 集合作为成员资格的测试。
    • 地图用作键查找。
    • 向量用作索引查找。
    • 关键字在 map 参数中用作查找。

    这个

    • 经常给你留个get
    • 允许您像问题一样将裸数据结构传递给高阶函数 比如filtermap,以及
    • 在关键字的情况下,允许您在地图和记录之间透明地移动 用于保存您的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-16
      • 2018-05-25
      • 2014-11-28
      • 2014-02-14
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多