不知道如何从clojure创建ISeq

时间:2016-10-26 04:56:43

标签: dictionary clojure hashmap

我想在clojure上使用下一个代码添加地图中的值:

(letfn [(r [l a]
          (if (empty? l)
            a
            (if (map? l)
              (r (first(vals l)) (+ a (first (vals l))))
              (r (rest l) (+ a (first l))))))]
  (r {:a 1 :b 2 :c 3} 0)

但是我收到以下错误:

  

IllegalArgumentException不知道如何创建ISeq:java.lang.Long clojure.lang.RT.seqFrom(RT.java:542)

3 个答案:

答案 0 :(得分:5)

问题是,在您的代码中,您正在empty上对l进行测试,而不确定l是否为seq。您应该在stacktrace中进一步了解:

  

不知道如何创建ISeq:java.lang.Long

               RT.java:  528  clojure.lang.RT/seqFrom
               RT.java:  509  clojure.lang.RT/seq
              core.clj:  137  clojure.core/seq
              core.clj: 5948  clojure.core/empty?      <------
                  REPL:   13  user/eval19330/r
                  REPL:   16  user/eval19330/r
                  REPL:   21  user/eval19330

这是因为作为(first (vals l))参数传递给下一次迭代的l是一个数字而不是一个seq,在您的情况下它只是值1

答案 1 :(得分:1)

您的函数r只能处理集合(当您调用empty?然后在map?上进行测试,否则调用rest)。你可能想要这样递归:

(letfn [(r [l a]
          (if (empty? l)
            a
            (if (map? l)
              (let [[key val] (first l)]
                (r (dissoc l key) (+ a val)))
              (r (rest l) (+ a (first l))))))]
  (list (r {:a 1 :b 2 :c 3} 0)
        (r [1 2 3] 0)))

答案 2 :(得分:0)

此代码将给出相同的错误:

(empty? (first (vals {:a 1 :b 2 :c 3})))

(empty? 2)

(concat [3] 2 [4])