【问题标题】:Wrong number of args (0) passed to: PersistentHashMap传递给的 args (0) 数量错误:PersistentHashMap
【发布时间】:2012-08-05 21:12:10
【问题描述】:

我对 Clojure 很陌生,我正在尝试通过移植我的一个代码来学习它,但是我目前遇到了以下问题:

=> lineup
{:c b4|b4|b3|b3, :sg b6|b11|b6|b6, :sf b7|b5|b5|b5, :pf b3|b1|b1|b1, :pg b10|b10|b11|b10}
=> (validate-lineup lineup)
ArityException Wrong number of args (0) passed to: PersistentHashMap  clojure.lang.AFn.throwArity (AFn.java:437)

函数如下:

(defn validate-lineup [lineup]
    (map (fn [position]
        ((hash-map (position 0)
            (map
                (fn [s] (.substring s 1))
                (str/split (position 1) #"\|"))
                ))
        ) lineup))

我正在尝试产生类似以下结果:

{:c {"4" "4" "3" "3"} :sg {"6" "11" "6" "6"} :sf {"7" "5" "5" "5"} ... }

感谢您的帮助,如果我没有以正确的“Lisp”方式编写,请教我如何。

【问题讨论】:

    标签: clojure


    【解决方案1】:

    你的主要问题在这里:

    (fn [position]
      ((hash-map (position 0)
                 (map
                   (fn [s] (.substring s 1))
                   (str/split (position 1) #"\|")))))
    

    您创建哈希映射,然后将其作为函数调用(注意hash-map 之前的双括号)。你可以删除它并得到这个:

    (fn [position]
      (hash-map (position 0)
                 (map
                   (fn [s] (.substring s 1))
                   (str/split (position 1) #"\|"))))
    

    这样validate-lineup会返回

    ({:c ("4" "4" "3" "3")} 
     {:sg ("6" "11" "6" "6")} 
     {:sf ("7" "5" "5" "5")} 
     {:pf ("3" "1" "1"` "1")} 
     {:pg ("10" "10" "11" "10")})
    

    但是您需要单个地图,而不是一系列地图。你可以合并它们:

    (apply merge (validate-lineup lineup))
    

    一些建议:

    使用subs 代替.substring(fn [s] (subs s 1))
    遍历地图时使用destructuring

    (fn [[key value]]
      (hash-map key
                 (map
                   (fn [s] (subs s 1))
                   (str/split value #"\|"))))
    

    有一种巧妙的方法可以使用into 函数从对向量创建映射。因此,您可以将lineup 转换为对的向量,其中对的第一项是键,第二项是数字列表:

    (defn validate-lineup [lineup]
      (into {} (map (fn [[key value]]
                        [key
                         (map #(subs s 1) (str/split value #"\|"))])
                 lineup)))
    

    您可以将b4|b4|b3|b3 解析为re-seq 的数字序列:

    user=> (re-seq #"\d+" "b1|b2|b3")
    ("1" "2" "3")
    

    最后你可以用for宏替换外部map

    (defn validate-lineup [lineup]
      (into {} (for [[key value] lineup]
                    [key (re-seq #"\d+" value)])))
    

    【讨论】:

    • 非常感谢,我后来意识到额外的括号,但我正在寻找类似你建议的东西,Clojure 与我一直在学习的东西非常不同。
    • 非常感谢,非常有用的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多