clojure - 在 Clojure 中是否有更好的方法来访问嵌套映射和向量?

标签 clojure clojure-core.logic

我正在从 here on freebase 获取一些 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/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-filters、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))])))

然后 (map #(extract-data % mapping) results) 应该可以解决问题

=> (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"}

这种类型的代码(查询解释器)可能很脆弱,所以一定要有一个测试套件。

关于clojure - 在 Clojure 中是否有更好的方法来访问嵌套映射和向量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13757122/

相关文章:

clojure - 对于 core.logic 来说,非关系在实践中意味着什么?

clojure - core.logic 中的伪关系

Prolog 匹配 vs miniKanren 统一

clojure - ClojureScript 中的 getElementsByClassName?

clojure - 在 Clojure 上使用自定义比较器对原始数组进行排序

java - 所有版本的 Clojure jar 报告为 Clojure-1.7.0-RC1,无论实际版本如何

clojure - Clojure core.logic 中的阶乘

clojure - 具有 -ve 值的 Core.logic 有限域

mongodb - 自动将 Mongodb ObjectId 映射到字符串和从字符串映射

clojure - 在 Clojure 中有更好的方法吗?