迭代Clojure中的json对象数组

时间:2018-10-20 13:18:37

标签: json clojure clojurescript reagent

我将使用Clojure实现一个宁静的API。对于GET请求,有一个网址,例如/List,我想从纯数据(是json文件)下面返回已解析的响应。 GET请求:

(GET "/list/:from-date/:to-date" [from-date to-date]
      wrap-json-response (response (parse-object from-date to-date all-records)))

如您所见,需要具有两个查询参数from-dateto-date。我需要一个名为parse-object的函数,该函数解析纯数据并将update-datefrom-dateto-date进行比较。如果update-date在这两个参数之间,则以预期的对象结构返回它。 下面是具有给定数据的纯对象和预期对象的结构。

纯数据(data.json):

[{"name": "JOHN",
  "update-date": "2017-11-10",
  "role": "admin"},
 {"name": "CHRIS",
  "update-date": "2018-04-28",
  "role": "user"},
 {"name": "ANNIE",
  "update-date": "2018-03-11",
  "role": "admin"}]

给出参数:from-date: 2017-11-01 to-date: 2018-04-28

预期的返回响应:

{"users":[
     {"role":"admin",
      "shows":[
            {"name":"JOHN",
             "status":"active"}]},
      {"role":"user",
       "shows":[
            {"name":"CHRIS",
             "status":"active"}]}]}

2 个答案:

答案 0 :(得分:0)

您可以使用Cheshire(https://github.com/dakrone/cheshire)之类的库在Clojure中进行JSON解析/打印。

您可以使用filter函数过滤数据:

(filter (fn [{:strs [update-date]}]
          (not (or (.before update-date from-date)
                   (.after update-date to-date))))
        objects)

您可以使用group-by重塑数据:

(group-by (fn [{:strs [role]}]
            role)
          objects)

并使用for表达式:

(for [[k xs] groups]
  {"role" k
   "shows" (for [x xs]
             (select-keys x ["name" "status"]))})

答案 1 :(得分:0)

此处概述了操作方法。我将把最终的格式留给您。

(ns tst.demo.core
  (:use tupelo.core demo.core tupelo.test)
  (:require
    [tupelo.string :as tstr] )
  (:import [java.time LocalDate]))

(def data-json
  "[{'name' : 'JOHN',
     'update-date' : '2017-11-10',
    'role' : 'admin'},
   {'name' : 'CHRIS',
     'update-date' : '2018-04-28',
    'role' : 'user'},
   {'name' : 'ANNIE',
    'update-date' : '2018-03-11',
    'role' : 'admin'}] ")

(dotest
  (let
    [date-from (LocalDate/parse "2017-11-01")
     date-to   (LocalDate/parse "2018-04-28")
     data-edn  (json->edn (tstr/quotes->double data-json))
     data-keep (vec
                 (remove nil?
                   (for [user-rec data-edn]
                     (let [update-date (LocalDate/parse (grab :update-date user-rec))]
                       (when (and
                               (.isBefore date-from update-date)   ; may need to add .isEqual
                               (.isAfter  date-to   update-date))  ; may need to add .isEqual
                         user-rec)))))]
    (spyx-pretty data-keep)))

有结果:

---------------------------------------------
   Clojure 1.10.0-alpha8    Java 1.8.0_161
---------------------------------------------

Testing tst.demo.core
data-keep => 
[{:name "JOHN",  :update-date "2017-11-10", :role "admin"}
 {:name "ANNIE", :update-date "2018-03-11", :role "admin"}]