在Clojure中是否有更好的方法访问嵌套贴图和向量?
我正在从中获取一些json(小心,您只能请求几次,而不使用在Clojure中是否有更好的方法访问嵌套贴图和向量?,clojure,clojure-core.logic,Clojure,Clojure Core.logic,我正在从中获取一些json(小心,您只能请求几次,而不使用&key=your key) 我想将响应转换为类似以下内容: ({:case "Roe v. Wade", :plaintiffs ("Norma McCorvey"), :defendants ("Henry Wade"), :court "Supreme Court of the United States", :subjects ("Abortion" "Privacy"), :article "http://wp/en/6
&key=your key
)
我想将响应转换为类似以下内容:
({:case "Roe v. Wade", :plaintiffs ("Norma McCorvey"), :defendants ("Henry Wade"), :court "Supreme Court of the United States", :subjects ("Abortion" "Privacy"), :article "http://wp/en/68493"} ...)
下面是我在使用clojure.data.json/read-string后产生的代码:
(defn extract-data [case]
{:case (case "name")
:plaintiffs (flatten (map #(get % "parties") (filter (fn [p] (some #(= (% "id") "/en/plaintiff") (p "role")))
(case "/law/legal_case/parties"))))
:defendants (flatten (map #(get % "parties") (filter (fn [p] (some #(= (% "id") "/en/defendant") (p "role")))
(case "/law/legal_case/parties"))))
:court (get-in case ["court" 0 "name"])
:subjects (map #(% "name") (case "subject"))
:article (get-in case ["/common/topic/article" 0 "source_uri" 0])})
(def response (-> query-uri
java.net.URL.
slurp
json/read-str))
(def case-data (map extract-data (response "result")))
提取数据似乎过于复杂,但有更好的方法吗?在这种情况下是否可以使用core.logic?如果是这样,怎么做?您可以查看不同的查询系统(zip筛选器、core.logic、datomic的集合数据日志等)。或者推出您自己的特别产品:
(defn select [x path]
(if-let [[p & ps] (seq path)]
(if (fn? p)
(mapcat #(select % ps) (filter p x))
(recur (get x p) ps))
x))
(def mapping
{:case ["name"]
:plaintiffs ["/law/legal_case/parties"
#(= (get-in % ["role" 0 "id" 0]) "/en/plaintiff")
"parties"]
:defendants ["/law/legal_case/parties"
#(= (get-in % ["role" 0 "id" 0]) "/en/defendant")
"parties"]
:court ["court" 0 "name" 0]
:subjects ["subject" (constantly true) "name"]
:article ["/common/topic/article" 0 "source_uri" 0]})
(defn extract-data [x mapping]
(into {}
(for [[k path] mapping]
[k (if (some fn? path) (select x path) (get-in x path))])))
然后(映射#(提取数据%mapping)结果)就可以完成这个任务
=> (extract-data (first result) mapping)
{:case "Roe v. Wade", :plaintiffs ("Norma McCorvey"), :defendants ("Henry Wade"), :court "Supreme Court of the United States", :subjects ("Abortion" "Privacy"), :article "http//wp/en/68493"}
这种类型的代码(查询解释器)可能很脆弱,因此一定要有一个测试套件。会有所帮助
(ns stackoverflow-answer.core
(:require [com.rpl.specter :refer :all]))
; your example data
(def case {"name" "Roe v. Wade"
"/law/legal_case/parties" [{"role" [{"id" "/en/plaintiff"}]
"parties" ["Norma McCorvey"]}
{"role" [{"id" "/en/defendant"}]
"parties" ["Henry Wade"]}]
"court" [{"name" "Supreme Court of the United States"}]
"subject" [{"name" "Abortion"}
{"name" "Privacy"}]
"/common/topic/article" [{"source_uri" ["http://wp/en/68493"]}]})
(defn specter-extract [case]
{:case (case "name")
:plaintiffs (select ["/law/legal_case/parties"
ALL
(selected? "role" ALL "id" (pred= "/en/plaintiff"))
"parties"
ALL]
case)
; etc
})
用法:
stackoverflow-answers.core=> (specter-extract case)
{:case "Roe v. Wade", :plaintiffs ["Norma McCorvey"]}