【问题标题】:Don't know how to create ISeq from clojure不知道如何从 clojure 创建 ISeq
【发布时间】:2016-10-26 04:56:42
【问题描述】:

我想用下面的代码从 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 不知道如何从:java.lang.Long clojure.lang.RT.seqFrom (RT.java:542) 创建 ISeq

【问题讨论】:

  • 你能用一个例子说明你想做什么吗?此外,(first(vals l)) 部分在“first”之后缺少一个空格。

标签: dictionary clojure hashmap


【解决方案1】:

问题在于,在您的代码中,您正在测试l 上的empty,而不确定l 是一个seq。您应该进一步查看堆栈跟踪:

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

               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

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

【讨论】:

    【解决方案2】:

    您的函数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)))
    

    【讨论】:

      【解决方案3】:

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

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

      还有

      (empty? 2)
      

      还有

      (concat [3] 2 [4])
      

      【讨论】:

        猜你喜欢
        • 2010-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多