=> (def persons '({:id 1 :name "olle"} {:id 2 :name "anna"} {:id 3 :name
"isak"} {:id 4 :name "beatrice"}))
=> (select [:id :name] from persons where [:id > 2] orderby :name)
({:id 4 :name "beatrice"} {:id 3 :name "isak"})
查询格式应为:
(select [columns]
from #{table}
where [:column op value]
orderby :column)
其中'op'等于'=''<' '>'或'<>'
(defmacro select
[vara _ coll _ wherearg _ orderarg]
'(map [~vara]
(filter [~wherearg]
(sort-by ~orderarg) ~coll)
)
)
我的解决方案还需要什么? 我不明白这些错误是什么意思,所以我甚至不知道应该寻找什么样的解决方案。
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom (RT.java:542)
答案 0 :(得分:1)
我会解决这个问题,坚持使用常规的Clojure语法,而不是尝试重新发明SQL。像这样:
jsonData
结果
(def persons '( {:id 1 :name "olle"}
{:id 2 :name "anna"}
{:id 3 :name "isak"}
{:id 4 :name "beatrice"} ))
(defn id-over-2?
[person]
(< 2 (:id person)))
(def persons-2 (filter id-over-2? persons) )
(def persons-3 (sort-by :name persons-2))
答案 1 :(得分:1)
使用Clojure方式,使用常规函数组合和宏语法糖:
您的具体示例可以解决如下:
(->> persons
(filter #(>= (:id %) 2))
(sort-by :name)
(map #(select-keys % [:id :name]))
但我们尝试创建一种更通用的解决方案。
(defn select
"Takes a set of keys as input, returns a transducer
which will select only the given keys for each item"
[& keys]
(map #(select-keys % keys)))
(defn filter-by [field predicate]
(filter #(-> % field predicate)))
(defn filter-by-name [user-name]
"Filters by users with the given name"
(filter-by :name #(= % user-name)))
(defn filter-by-age [user-age]
"Filters by users with the given age"
(filter-by :age #(= % user-age))
(defn filter-by-age-over [user-age]
"Filters by users with the age strictly above user-age"
(filter-by :age #(> % user-age))
(defn filter-by-age-below [user-age]
"Filters by users with the age strictly below user-age"
(filter-by :age #(< % user-age))
(defn filter-by-id-over [id-val]
(filter-by :id #(> % id-val))
(defn filter-by-gender [gender]
(filter-by :gender #(= % gender))
我们现在可以使用以下这些功能
(def xf-charly-age-5
(comp (filter-by-name "Charly")
(filter-by-age 5)
(select :name :id)))
(defn xf-adults
(comp (filter-by-age-over 18)
(select :name :id)))
(defn xf-male-adults
(comp (filter-by-age-over 18)
(filter-by-gender :male)
(select :name :id)))
(defn search-users [xf users]
(->> (into [] xf users)
(sort-by
您现在可以使用以下内容:
(search-users xf-male-adults all-users)
(search-users xf-adults all-users)
(search-users xf-charly-age-5 all-users
有关排序的说明:
不幸的是,Clojure没有配备分类传感器。但是,您可以从https://github.com/cgrand/xforms项目中获取一个项目,或使用sort-by
函数自行实施排序。