使用Clojure提取嵌套结构JSON数据的方法求助
嘿,我懂你在学Clojure写JSON分析程序时遇到的提取数据的难题了!咱们对着你给出的示例数据,一步步拆解怎么操作——Cheshire把JSON转成Clojure的map和vector后,用原生函数就能轻松搞定。
先把你的示例数据整理成可操作的代码块方便参考:
(def sample-data {:id "0", :data [{:name "item1 x 1", :price {:GBP 9.99}} {:name "Delivery", :price {:GBP 3.49}}], :date {:date "2014-01-12T01:21:28.000Z"}, :total ...})
常用的数据提取方法
1. 提取顶层简单字段
要是拿订单ID、日期这类顶层或浅层级的字段,直接用键访问或者get函数就行,两种写法都很直观:
;; 获取订单ID (:id sample-data) ; => "0" ;; 或者用get(好处是可以指定默认值,避免nil报错) (get sample-data :id "默认ID") ; => "0" ;; 获取订单日期字符串 (:date (:date sample-data)) ; => "2014-01-12T01:21:28.000Z"
2. 提取深层嵌套字段
遇到多层嵌套的情况,比如要拿某个商品的英镑价格,用get-in会比多层键访问更清晰,不容易出错:
;; 获取第一个商品的GBP价格 (get-in sample-data [:data 0 :price :GBP]) ; => 9.99 ;; 获取配送费的GBP价格 (get-in sample-data [:data 1 :price :GBP]) ; => 3.49
get-in的参数是数据本身,加上一个路径向量——向量里的元素就是每层的键(列表的话用索引,比如:data是vector,所以用0取第一个元素)。
3. 批量提取列表里的所有数据
如果要把:data里所有商品的名称和价格都捞出来,用map遍历就行,还能顺便整理成你需要的格式:
;; 提取所有商品的名称和对应的GBP价格 (map (fn [item] {:商品名称 (:name item) :英镑价格 (:GBP (:price item))}) (:data sample-data)) ;; 执行后会得到: ;; ({:商品名称 "item1 x 1", :英镑价格 9.99} {:商品名称 "Delivery", :英镑价格 3.49})
4. 用解构简化代码
Clojure的解构语法能让你直接“拆”出需要的数据,代码会更简洁易读,比如:
;; 顶层解构,直接取出id、date、data三个字段 (let [{:keys [id date data]} sample-data] (println "订单ID:" id) (println "订单日期:" (:date date)) (println "所有商品:" data)) ;; 嵌套解构,一步拿到第一个商品的名称和价格 (let [{[first-item] :data} sample-data {:keys [name price]} first-item {:keys [GBP]} price] (println "第一个商品:" name "价格:" GBP))
至于你示例里的:total字段,不管它是直接数值还是嵌套结构,用上面的方法都能搞定——比如如果是{:total {:GBP 13.48}},那(get-in sample-data [:total :GBP])就能拿到总价了。
如果还有特定的需求(比如过滤某个商品、计算总价总和),随时调整这些方法就行,Clojure的序列操作对这类嵌套数据特别友好~
内容的提问来源于stack exchange,提问作者Gary Richardson
相关产品推荐
相关产品推荐

