Clojure:确定地图值的函数

时间:2013-07-02 13:50:07

标签: clojure

我越想到这个问题,看起来就越错误......

我在程序中定义了类似'map constructor'的东西。这背后的想法是我有一个通用的地图结构来处理一些“项目”,但我想对特定类型的项目强制执行一些默认值。

我遇到的问题是这个'map构造函数'有一个k-v对,并且该对的值应该由使用该映射的函数确定(在下面的例子中可能会更清楚)。

我的第一个想法是引用值中的表达式,然后在所述函数中对其执行eval。第二个想法是用fn替换值,但这似乎返回类似于引用的表达式。

让我试着描绘一下这个问题:

  • 模型结果图应该类似{:a 1:b 2:c 3}
  • 构造函数类似于

    (defn cons-field [b]
      {:a (fn [name] (str name "!"))
       :b b
       :c "default"})
    
  • 项目已创建(def a-field (cons-field 5))

  • 使用地图的调用函数类似于

     (defn the-function [name field]
       (str (get-in field [:a])))
    

现在我需要的是:a的值是'--function'中参数名称的函数。当然最后一个功能不起作用,我不确定它是否是正确的方法。 ':a'键并不总是fn;有时它只是一个字符串文字。有什么想法吗?

干杯!

2 个答案:

答案 0 :(得分:0)

所以这就是我在A. Webb和Jeremy Heiler的评论之后解决这个问题的方法。

初始构造函数已更改为:

(defn cons-field [b]
  {:a nil ; either delete completely or comment that
          ; the case will be handled by the caller
   :flag xx ; true or :case-qualifier
   :b b
   :c "default"})

调用函数已更改为:

(defn the-function [name field]
  (let [case-q (:flag field)]
    (cond
      (= case-q :case-qualifier) (get-name name) ; you can have many different cases
                                              ; conciser using constants for these qualifiers
      (...) ()))) ; else as normal

然后最初放入地图的逻辑进入不同的函数:

(defn get-name [name] (str name "!"))

希望这有助于其他人:)

答案 1 :(得分:0)

根据您发布的内容,无法真正理解您的问题。我能为你做的只是告诉你你提供的代码是做什么的,并猜测你希望它做什么。

(def r (cons-field 5))创建哈希地图r(r :b) = 5,(r :c) =“默认”和(r :a) = (fn [name] (str name "!"))。如您所见,(r :a)的结果和(r :c)的结果都与r或5无关。

如果上面描述的结果是您想要的,那么进行一些重构是合乎逻辑的:

(def default-field {:a (fn [name] (str name "!"))
                    :c "default"})

(def cons-field (partial assoc default-field :b))

关于the-function:对(get-in field [:a])的调用与(field :a)相同,并返回函数(fn [name] ...)the-function将使用str对此fn进行字符串化,并且很可能会返回类似“user.fn $ 23092 ....”的内容。

如果您希望the-function返回调用(fn [name] ...)的结果并将名称传递给该函数,则需要按如下方式更改the-function

(defn the-function 
  [name field]
  (str ((field :a) name)))

如果你希望the function根据a的实际值返回其他内容,你可以检查它是否是一个函数并用名称调用它,否则返回值。

(defn the-function
  [name field]
  (when-let [v (field :a)]
    (or (when (fn? v)
          (v name))
        v)))

现在从你自己的答案中读到我对你想要解决的实际问题更加困惑,但我希望这个答案可以提供帮助。