如何将json文件读入Clojure defrecord(稍后搜索)
我在Clojure REPL中创建了一个defrecord:如何将json文件读入Clojure defrecord(稍后搜索),json,clojure,Json,Clojure,我在Clojure REPL中创建了一个defrecord: user=> (defrecord Data [column1 column2 column3]) user.Data 如何通过读取.json文件自动将数据添加到此记录?defrecord中的每一列都与json数据中的一个键完全对应。如果文件包含一条记录,则其外观类似于: [ { "column1" : "value1" "column2" : "value2" "column3" : "value
user=> (defrecord Data [column1 column2 column3])
user.Data
如何通过读取.json文件自动将数据添加到此记录?defrecord中的每一列都与json数据中的一个键完全对应。如果文件包含一条记录,则其外观类似于:
[
{
"column1" : "value1"
"column2" : "value2"
"column3" : "value3"
}
]
但档案中有数千条这样的记录
我可以像这样含糊地描述文件的内容:
(json/read-json (slurp "path/to/file.json")))
read json函数的依赖项被添加到project.clj文件中,该文件位于我从命令行运行lein repl
的目录中::dependencies[org.clojure/data.json“0.2.1”]
我只希望能够使用Clojure函数搜索记录的值,以便传递给搜索函数的值介于单个记录的column1和column2值之间(即,n-record.column1.value
我想你认为记录比地图更适合这种情况,据我所知,你没有使用任何让记录变得特别的功能,比如多态性。也许有一种方法可以让柴郡吐出记录,但我不想麻烦。使用
数据.json
包:
(require '[clojure.data.json :as json])
将值读入内存:
(def all-records (json/read-str (slurp "path/to/file.json")
:key-fn keyword))
;; ==> [ { :column1 "value1", :column2 "value2", :column3 "value3" }, ...]
查找匹配的记录:
(def query "some-value")
(def matching (filter #(and (< (:column1 %) query) (< query (:column2 %))) all-records))
将所有信息收集在一起(并使其更加灵活):
(定义查找匹配[选择fn结果fn记录]
(映射结果fn(过滤器选择fn记录)))
(在[rec query]中定义select)
(和(<(:column1rec)查询)(<查询(:column2 rec)))
(查找匹配的#(在%范围内选择“某些值”):第3列所有记录)
ffriend,非常感谢您的帮助。我在查找匹配函数时仍然遇到一些问题。repl抱怨我没有向该函数传递足够的参数。是否所有记录都应在:column3之后作为第三个参数传递?@ChrisDevo:是的,抱歉,手头没有repl。我已更新了代码。映射中的值存储为字符串。要进行数字比较,我必须将(:column1 rec)
修改为(bigint(:column1 rec))
,否则我将得到ClassCastException java.lang.String不能转换为java.lang.Number clojure.lang.Numbers.lt(Numbers.java:219)
抛出。谢谢,gtrak。我也不确定是否需要defrecords。我仍然习惯于函数范式,其中代码就是数据,反之亦然。
(map :column3 matching)
(defn find-matching [select-fn result-fn records]
(map result-fn (filter select-fn records)))
(defn select-within [rec query]
(and (< (:column1 rec) query) (< query (:column2 rec))))
(find-matching #(select-within % "some-value") :column3 all-records)