Clojure 中的惯用模式函数

2024-03-22

我正在学习 Clojure,想要一些关于惯用用法的建议。作为小型统计包的一部分,我有一个计算一组数据的众数的函数。 (背景:众数是一组数据中最常见的值。几乎有十几种已发布的算法来计算它。这里使用的算法来自 Bernard Rosner 的《生物统计学基础》第 6 版。)

(defn tally-map
 " Create a map where the keys are all of the unique elements in the input
   sequence and the values represent the number of times those elements
   occur. Note that the keys may not be formatted as conventional Clojure
   keys, i.e. a colon preceding a symbol."
  [aseq]
  (apply merge-with + (map (fn [x] {x 1}) aseq)))

(defn mode
 " Calculate the mode. Rosner p. 13. The mode is problematic in that it may
   not be unique and may not exist at all for a particular group of data.
   If there is a single unique mode, it is returned. If there are multiple
   modes, they are returned as a list. If there is no mode, that is all
   elements are present in equal frequency, nil is returned."
  [aseq]
  (let [amap (tally-map aseq)
        mx (apply max (vals amap))
        k (keys amap)
        f (fn [x] (not (nil? x)))
        modes (filter f (map #(if (= mx (get amap %)) %) k))
        ]
    (cond (= 1 (count modes)) (first modes)
      (every? #(= mx %) (vals amap)) nil
      :else modes)
    )
  )

我有几个问题:

  1. 论点。该函数接受单个序列。像加法函数这样接受可变数量的参数是否更惯用?
  2. 代码气味。看起来“let”比它应该的要复杂一些——这么多的变量赋值。我是否错过了语言或库的任何明显(或不那么明显)的用法,这些用法将使该方法更加简洁?

先谢谢您的帮助。


在我看来,将某些函数映射到集合上,然后立即将列表压缩为一项是一个使用的标志reduce.

(defn tally-map [coll]
  (reduce (fn [h n]
            (assoc h n (inc (h n 0))))
          {} coll))

在这种情况下我会写modefn 将单个集合作为参数,就像您所做的那样。我能想到对这样的函数使用多个参数的唯一原因是,如果您计划必须大量键入文字参数。

所以如果例如这是一个交互式 REPL 脚本,您经常会输入(mode [1 2 1 2 3])从字面上看,那么您应该让该函数接受多个参数,以免您输入额外的内容[]一直在函数调用中。如果您计划从文件中读取大量数字,然后采用这些数字的众数,则让该函数采用一个作为集合的参数,这样您就可以避免使用apply每时每刻。我猜你最常见的用例是后者。我相信apply还增加了当您有一个采用集合参数的函数调用时可以避免的开销。

我同意其他人的观点,你应该有mode即使只有一个结果,也返回结果列表;它会让你的生活更轻松。也许重命名它modes当你在做的时候。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Clojure 中的惯用模式函数 的相关文章

  • 如何在 R 中重新格式化表格?

    我加载了一个这样的表 V1 V2 V3 pat1 1 2 pat1 3 1 pat1 4 2 pat2 3 3 pat3 1 4 pat3 2 3 我需要将其格式化为如下所示 其中 V1 表示行 V2 表示列 V3 中的值 1 2 3 4
  • 人们可以放心地忽略宏和内置宏之间的区别吗?

    我从 Clojure 开始 这也是我的第一个 lisp 显然有很多东西需要吸收 为了减轻认知负担 我尝试找到我可以安全地忽略的部分 目前 人们能否安全地以相同的方式处理带有宏的表单和带有内置函数的表单 或者是否会出现以后出现的陷阱 换句话说
  • dnorm 是如何工作的?

    我对统计和 R 很陌生 也许这是一个非常微不足道的问题 但我不太明白这是如何工作的 假设我使用dnorm 5 0 2 5 这意味着什么 我看到一些资源 他们告诉我这个函数计算密度曲线中点的高度 现在我再次读到 在连续分布中 数字的确切概率为
  • 懒惰的 juxt 函数有什么优点吗?

    在回答中一个问题 https stackoverflow com questions 10044254 is there a reverse map function关于一个使用相同参数映射多个函数的函数 A juxt 我想出了一个基本上采
  • 从二元高斯分布生成均值

    我正在阅读统计学习要素ESLII http www stat stanford edu tibs ElemStatLearn 在第二章中 他们用高斯混合数据集来说明一些学习算法 为了生成该数据集 他们首先从二元高斯分布 N 1 0 I 生成
  • 为什么 R 中的重新编码没有改变原始值?

    我正在尝试使用recode在 R 中 来自car包 并且它不起作用 我将 csv 文件中的数据读入名为的数据框中results 然后 我替换列中的值Built year 根据以下逻辑 recode results Built year 2
  • 为从 nginx 反向代理转发的请求添加唯一 id

    我们运行 nginx 作为反向代理 将请求转发到运行 Compojure 的 Clojure 应用程序 Compojure 是一个封装 Jetty 的库 为我们的应用程序提供服务 Web 请求的能力 目前 我们捕获 nginx 和 Cloj
  • 如何使用 core.async 在 Clojure 中写入日志文件?

    我想使用 core async 作为写入文件的记录器 因此我创建了一个 test txt 文件 将其粘贴在我的资源文件夹中并编写了以下代码 use clojure java io use clojure core async def pri
  • 为什么“(def 元音?(set“aeiou”))”有效?

    我正在看优秀的 Clojure 教程here http ociweb com jnb jnbMar2009 html 在其中一个示例中 它具有如下所示的 Clojure 代码 def vowel set aeiou 这使得元音对于元音返回
  • 什么时候应该在 Clojure 中使用临时重新绑定特殊变量这一习惯用法?

    我注意到一些库 例如 clojure twitter 使用特殊的变量 用于动态绑定的变量 被星号包围 进行 oauth 身份验证 您将身份验证保存在 var 中 然后使用 with oauth myauth 我认为这是解决此类问题的一个非常
  • 在 Clojure 中递归反转序列

    我想在 Clojure 中反转序列而不使用reverse函数 并递归地执行此操作 这是我想出的 defn reverse recursively coll loop r rest coll acc conj first coll if co
  • 从 JVM 线程本地空间卸载 Clojure 变量

    我正在 Clojure 中为 BaseX 编写一个插件 通过 lein uberjar 构建 并包含 Clojure 解释器 在大多数情况下 这效果很好 然而 当通过 BaseX HTTP 实例运行时 评估在 Jetty 的线程池内进行 而
  • 如何编写循环来运行数据框的 t 检验?

    我遇到了对数据框中存储的某些数据运行 t 检验的问题 我知道如何一一做 但效率很低 请问如何写一个循环来实现呢 例如 我在testData中获取了数据 testData lt dput testData structure list Lab
  • 有效地将相似的数字分组在一起[重复]

    这个问题在这里已经有答案了 可能的重复 一维数数组聚类 https stackoverflow com questions 11513484 1d number array clustering 我有一个数字数组 例如 1 20 300 4
  • 为什么 clojure future 会阻塞主线程?

    我有一个简单的 lein 项目 其中 main包含一个未来 def f future 42 defn main args println f 当我跑步时lein run它打印42但不返回 我不明白为什么它不返回 如何得到lein run回来
  • 为什么leiningen启动时那么慢?

    我在用着lein repl在控制台中执行 clojure repl 当我运行它时 需要超过15秒 当我跑步时java cp clojure 1 6 0 jar clojure main 只需几秒钟 Why is lein repl太慢了 有
  • 这两个 clojure 函数之间有什么区别和问题?

    对于课程项目的一部分 我正在实现一个函数来从文件中读取一些数据并根据该文件创建图形结构 一整天我问了几个问题 结果就是这样 下面是一个可以正常工作的函数 它首先以惰性序列的形式读入文件 然后循环解析每一行并将其打印出来 defn print
  • 将箱线图与 Wilcoxon 检验进行比较

    我正在使用 R 中的 ggplot2 包比较两组长度 不同的个体 和箱线图 我想比较这两个分布 但到目前为止我发现使用 wilcoxon 测试的唯一方法是 ggpubr 包中的 stat compare means 这是比较分布的正确方法吗
  • Clojure Web 应用程序 - 我从哪里开始?

    最近我一直在研究 Clojure 我喜欢这门语言 我想看看我是否可以在其中制作一个小型网络应用程序 只是为了挑战自己 但是 我完全没有设置任何与 Java 相关的 Web 应用程序的经验 事实上 我对 Java 并没有太多的经验 我从哪说起
  • Clojure读行函数问题

    我试图在我的 Clojure 程序中获取控制台输入 但是当它到达程序的该部分时它给我这个错误 Exception in thread main java lang ClassCastException clojure lang LineNu

随机推荐