下面是我尝试迭代一系列地图;由于转换错误导致代码失败:Exception in thread "main" java.lang.RuntimeException: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to java.util.Map$Entry
。
任何人都可以解释/演示我应该如何迭代结果集吗?感谢。
(with-connection db
(with-query-results rs ["select category from users group by category"]
(doall
(for [s [rs]]
(do (println (val s)))))))
答案 0 :(得分:5)
您将rs
打包到矢量中。因此s
将绑定到整个序列,而不是单个映射条目。因此,当您致电val
时,它不知道如何处理序列。因此例外。这应该有效:
(with-connection db
(with-query-results rs ["select category from users group by category"]
(doall
(for [rec rs
s rec]
(do
(println (val s)))))))
然而,doall
周围的丑陋do
和for
应响铃,可以改善一些事情。实际上for
用于构造另一个懒惰序列。对于您的示例中的打算,这不适用于副作用。在这种情况下,您应该使用doseq
。
(with-connection db
(with-query-results rs ["select category from users group by category"]
(doseq [rec rs
s rec]
(println (val s)))))
doseq
的绑定界面与for
的界面相同。然而,它立即执行,因此立即实现任何副作用。如果在for的主体中放置多个表达式,则必须将其包装到do
中。这提醒人们身体应该产生价值。然而,多个表达指示副作用。因此doseq
将身体包裹成do
。所以你可以轻松拥有多个表达式。例如:
(doall
(for [s seq-of-maps]
(do
(println (key s))
(println (val s)))))
(doseq [s seq-of-maps]
(println (key s))
(println (val s)))))
根据经验,你需要副作用吗?寻找以do
开头的东西!
根据经验2:如果看起来很丑陋(参见上面的比较),这应该响铃。
答案 1 :(得分:1)
好的,所以听起来你正在尝试从Clojure进行数据库查询。例如,您可能必须提供有关“users”表的更多信息以及查询结果集的外观。
无论如何,像这样的东西可以工作
(def a (with-query-results rs ["select category from users group by category"]
(doall rs)))
(map #(:category %) a)