Clojure:我如何获取函数列表,转换它们,并返回带有它们原始名称的映射?
好的,假设我有一个函数列表: [f1 f2 f3] 我还有一个转换函数,我们称之为“trans” 我要做的是将trans应用于原始列表中的每个函数,并返回一个映射,其键是与原始fxn名称相对应的符号,其值是这些函数的转换版本:Clojure:我如何获取函数列表,转换它们,并返回带有它们原始名称的映射?,clojure,Clojure,好的,假设我有一个函数列表: [f1 f2 f3] 我还有一个转换函数,我们称之为“trans” 我要做的是将trans应用于原始列表中的每个函数,并返回一个映射,其键是与原始fxn名称相对应的符号,其值是这些函数的转换版本: {:f1 (trans f1) :f2 (trans f2) :f3 (trans f3)} 这可能是一个非常简单的问题,但我在获取将函数名转换为符号所需的元数据时遇到了困难。如果您的初始列表包含实际函数,而不是包含解析为此类变量的函数或符号的变量,则通常没有规范的方法
{:f1 (trans f1) :f2 (trans f2) :f3 (trans f3)}
这可能是一个非常简单的问题,但我在获取将函数名转换为符号所需的元数据时遇到了困难。如果您的初始列表包含实际函数,而不是包含解析为此类变量的函数或符号的变量,则通常没有规范的方法为它们指定名称,Clojure中的as函数不一定有名称。您可以获取函数对象的类的名称,并像处理它一样处理它,以获得类似于人类可读的“名称”,但可能无法从该名称转到函数。因此,在处理函数列表时,您可能需要考虑提供一个明确的名称列表。 如果列表中包含符号,则可以执行以下操作:
(zipmap fs (map (comp trans deref resolve) fs))
其中,fs
是用于生成映射的输入列表,其中,fs
的成员作为键,存储在由fs
的成员命名的变量中的转换函数作为值。(如果您希望将符号转换为关键字以匹配问题文本中显示的所需输出,可以使用(映射关键字fs)
作为zipmap
的第一个参数)
类似地,如果您有一个Vars列表,您可以从Vars中提取名称空间和符号名称(使用interop表单访问
clojure.lang.Var
的相关字段,即sym
和ns
),同时使用deref
获取要馈送到trans
的函数。(严格来说,一个变量可能没有名称空间或符号名附加到它上——请参见与本地变量的关系;但是,这样的变量并不经常使用,因此您可以合理地将其作为列表转换契约的一部分,它希望在其输入中找不到任何变量。)您可以尝试如下所示的宏。您需要将函数列表直接传递给宏
(defmacro fn-to-map [fns trans-fn]
`~(into {} (map #(-> [(-> % name keyword) `(~trans-fn ~%)]) fns)))
例如:
(let [f1 inc
f2 dec
f3 print]
(fn-to-map [f1 f2 f3] identity))