使用 Clojure 在数据库上循环

Looping on a database with Clojure

我刚开始 Clojure Heroku,第一次阅读 this introduction。 现在处于亲自动手的阶段,我面临着循环处理数据库的问题。

这是有效的:

(for 
  [s (db/query (env :database-url)
                   ["select * from My_List"])]
      ; here one can do something with s, for example:
      ; print out (:field s)
)

但我想更新循环内的变量是不够的。 阅读该主题,我了解到 Clojure 有自己的处理变量的方式,我需要使用循环模式。

这是我尝试过的:

(loop [a 0 b 1
       s (db/query (env :database-url)
                 ["select * from My_List"])]
      ; here I want to do something with s, for example
      ; print out (:field s)
      ; and do the following ... but it does not work!
  (if (> (:otherField s) 5)
    (:otherField s)
    (recur (+ a (:otherField s)) b s))
)

因为我在写这篇文章之前尝试了各种方法 post,所以我知道上面的代码是有效的,除了我在数据库方面做错了什么。

所以我的问题来了:我需要更改什么才能使其正常工作?

我明白了,当你习惯了不同的范式时,一开始很难进入功能性思维。

我认为没有关于“如何正确执行此循环”的正确解释,因为在这里执行循环是不正确的。

我觉得最不对的两件事:

  1. 永远不要做 SELECT * FROM table。这不是关系数据库的使用方式。例如,当您希望所有值的总和大于 5 时,您应该这样做:SELECT SUM(field) FROM my_list WHERE field > 5

  2. 不要循环思考(怎么做)而是想做什么数据:

    • 我想在外地工作 :otherFIeld
    • 我只对大于 5 的值感兴趣
    • 我要所有剩余值的总和

然后你会遇到这样的事情:

(reduce +
        (filter #(> % 5)
                (map :otherField
                     (db/query (env :database-url) ["select * from My_List"]))))

(完全没有循环。)