美文网首页
clojure爬坑之项目里处理过的复杂逻辑

clojure爬坑之项目里处理过的复杂逻辑

作者: 小马将过河 | 来源:发表于2019-07-31 19:19 被阅读0次

    1、一个高阶函数的使用:将db查询结果日期进行format,并且group和求sum,重新组织结构

    从DB中查到的map结果集如下:

    (alk-wxapi.db.db-patient/get-patient-cost
      {:page       0,
       :size       10,
       :patient-id 222})
    =>
    ({:deleted 0,
      :drug-flag 1,
      :drug-id 1,
      :cost-date #object[java.time.LocalDate 0x2d30b554 "2019-05-07"],
      :id "1",
      :create-time #object[java.time.LocalDateTime 0x76211aed "2019-06-05T22:42:14"],
      :count 2,
      :drug-name "安脱达",
      :patient-id "222",
      :sum 58.0}
     {:deleted 0,
      :drug-flag 1,
      :drug-id 1,
      :cost-date #object[java.time.LocalDate 0x9e55443 "2019-06-05"],
      :id "3",
      :create-time #object[java.time.LocalDateTime 0x7114ec3c "2019-06-05T22:42:01"],
      :count 10,
      :drug-name "安脱达",
      :patient-id "222",
      :sum 120.0}
     {:deleted 0,
      :drug-flag 1,
      :drug-id 4,
      :cost-date #object[java.time.LocalDate 0x59267d5f "2019-05-07"],
      :id "2",
      :create-time #object[java.time.LocalDateTime 0x27aef2e4 "2019-06-05T22:41:50"],
      :count 15,
      :drug-name "奥马珠",
      :patient-id "222",
      :sum 200.0})
    
    

    json以后格式是一条条的record:

    "data": [
          {
            "deleted": 0,
            "drug-flag": 1,
            "drug-id": 1,
            "cost-date": "2019-05-07",
            "id": "1",
            "create-time": "2019-06-05T22:42:14",
            "count": 2,
            "drug-name": "安脱达",
            "patient-id": "222",
            "sum": 58
          },
          {
            "deleted": 0,
            "drug-flag": 1,
            "drug-id": 1,
            "cost-date": "2019-06-05",
            "id": "3",
            "create-time": "2019-06-05T22:42:01",
            "count": 10,
            "drug-name": "安脱达",
            "patient-id": "222",
            "sum": 120
          },
          {
            "deleted": 0,
            "drug-flag": 1,
            "drug-id": 4,
            "cost-date": "2019-05-07",
            "id": "2",
            "create-time": "2019-06-05T22:41:50",
            "count": 15,
            "drug-name": "奥马珠",
            "patient-id": "222",
            "sum": 200
          }
        ]
    

    而预期的json是干这么几件事:

    1、根据日期将分组,以指定字段为key,group的日期为value
    2、对日期进行格式化
    3、同一日期下的数据,以list为key,record作为value
    4、对每个list里record的sum字段求和,与list同级,以total-cost为key,和为value
    5、同4类似,对list里的record的count求和,与list同级,以total-count为key,和为value

    {
    "content": [
          {
            "cost-date": "2019-05-07",
            "list": [
              {
                "deleted": 0,
                "drug-flag": 1,
                "drug-id": 1,
                "cost-date": "2019-05-07",
                "id": "1",
                "create-time": "2019-06-05T22:42:14",
                "count": 2,
                "drug-name": "安脱达",
                "patient-id": "222",
                "sum": 58
              },
              {
                "deleted": 0,
                "drug-flag": 1,
                "drug-id": 4,
                "cost-date": "2019-05-07",
                "id": "2",
                "create-time": "2019-06-05T22:41:50",
                "count": 15,
                "drug-name": "奥马珠",
                "patient-id": "222",
                "sum": 200
              }
            ],
            "total-cost": 258,
            "total-count": 17
          },
          {
            "cost-date": "2019-06-05",
            "list": [
              {
                "deleted": 0,
                "drug-flag": 1,
                "drug-id": 1,
                "cost-date": "2019-06-05",
                "id": "3",
                "create-time": "2019-06-05T22:42:01",
                "count": 10,
                "drug-name": "安脱达",
                "patient-id": "222",
                "sum": 120
              }
            ],
            "total-cost": 120,
            "total-count": 10
          }
        ]
    }
    

    那么这个处理函数应该怎么写呢?
    提供一个工具类,处理将关系数据库的record搞成tree的函数

    (defn group-data-by-keys
      "对一组数据库返回结果{data}进行处理, 使用{group-keys}中的key进行group-by:
      (sut/group-data-by-keys test-dict
                                      [:group-code1
                                       :group-code2]
                                      )
      可以带多组额外的集合函数,多组[key reducing-function init-value]的格式:
      (sut/group-data-by-keys test-dict
                                      [:group-code]
    
                                      :a
                                      (fn [v e] (+ v (:id e)))
                                      0
    
                                      :b
                                      (fn [v e] (+ v (:id e)))
                                      0
                                      )"
      ([data group-keys]
       (->> data
            (group-by (fn [m] (select-keys m group-keys)))
    
            (reduce-kv (fn [m k v]
                         (assoc m k {:list
                                     (mapv
                                      (fn [e]
                                        (apply dissoc e group-keys))
                                      v)}))
                       {})
            (mapv (fn [e] (apply merge e)))))
    
      ([data group-keys key r-func val & krvs]
       (->> data
            (group-by (fn [m] (select-keys m group-keys)))
    
            (reduce-kv (fn [m k v]
                         (assoc m
                                k (if (empty? krvs)
                                    {:list
                                     (mapv
                                      (fn [e]
                                        (apply dissoc e group-keys))
                                      v)
                                     key (reduce r-func val v)}
    
                                    (apply assoc {:list
                                                  (mapv
                                                   (fn [e]
                                                     (apply dissoc e group-keys))
                                                   v)
                                                  key (reduce r-func val v)}
    
    
                                           (let [krvs-seq (partition 3 krvs)]
                                             (mapcat (fn [krv]
                                                       (let [[key r-func val] krv]
                                                         [key (reduce r-func val v)]))
                                                     krvs-seq))))))
    
                       {})
            (map (fn [e] (apply merge e))))))
    

    再提供一个相反作用的函数

    (defn list-from-group-by
     "去除分组, 作用和group-data-by-key 相反:
      一层嵌套: (list-from-group-by {:y 1 :a [{:b 2} {:b 3}]} )))  ->  [{:b 2, :y 1} {:b 3, :y 1}]
    
    
     双层嵌套:  (mapcat sut/list-from-group-by
                      (sut/list-from-group-by {:y 1 :a [{:b [{:x 99}]} {:b [{:x 77}]}]} ))
    
               ->
    
               [{:x 99, :y 1} {:x 77, :y 1}]
     "
     [m]
     (reduce-kv (fn [r k v]
                 (if (vector? v)
                  (->> (apply conj r v)
                       (map #(merge % (dissoc m k))))
    
                  r))
                []
                m))
    

    2、一些有用的utils

    
    (defn lower-case-keywrod
     "把输入的字符串变成keywrokd \"ABC\" -> :abc "
     [s]
     (keyword (clojure.string/lower-case s)))
    
    
    (defn parse-int
      "string 转 int"
      [s]
      (Integer/parseInt (re-find #"\A-?\d+" s)))
    
    (defn parse-double
      "string 转 doule"
      [s]
      (Double/parseDouble (re-find #"\A-?\d+" s)))
    

    3、筛选和判断一组数据中不为nil的

    有这么一组数:

    (def x '[(nil nil nil nil nil) (nil nil nil nil nil) ({:drug-id "300", :drug-name "西替利嗪,左西替利嗪(仙特朗,优泽)", :checked true, :dosage "1111", :dosage-unit "滴/天"} nil {:drug-id "302", :drug-name "谈说斯汀(UPDATE)", :checked true, :dosage "1111", :dosage-unit "滴/天"} nil) ()])
    

    找出不为nil的

    (filter (complement nil?) (mapcat identity x))
    

    4、在数组中找出符合条件的元素

    (first (filter (complement nil?)
            [a b]))
    
    (first (filter #(= % :a) [:a :b :c :d]))
    

    some实现

    (some #{:a} [:a :b :c :d])
    

    因为set也是一个函数

    • 如何快速返回,不用全部遍历呢?-------在reduce中使用reduced 函数
      如果我们想一旦求和的结果大于100,我们就返回:big,并且中断计算。
    (reduce (fn [a v] (if (< a 100) (+ a v) (reduced :big))) (range 10))
    

    返回值:45

    (reduce (fn [a v] (if (< a 100) (+ a v) (reduced :big))) (range 20))
    

    返回值::big

    5、类似第一条,将json数据转成map,并做拼接处理。

    需要实现的添加和详情页面效果如下,


    add

    需要后台在详情接口将数据拼接好:


    UI
    db中存储的是json,通过(db/get-reaction-detail {:id id})查找到的原始数据结构:
    {
            "id": "2",
            "reaction": [
                {
                    "list": [
                        {
                            "show": true,
                            "value-id": 53,
                            "parent-id": 52,
                            "group-code": "REACTION",
                            "dict-value-code": "SHOUBIZHONGZHANG",
                            "dict-value-name": "手臂肿胀",
                            "dict-value-sort": 1
                        },
                        {
                            "show": false,
                            "value-id": 54,
                            "parent-id": 52,
                            "group-code": "REACTION",
                            "dict-value-code": "RE",
                            "dict-value-name": "热",
                            "dict-value-sort": 2
                        },
                        {
                            "show": false,
                            "value-id": 55,
                            "parent-id": 52,
                            "group-code": "REACTION",
                            "dict-value-code": "TENTTONG",
                            "dict-value-name": "疼痛",
                            "dict-value-sort": 3
                        },
                        {
                            "show": true,
                            "value-id": 56,
                            "parent-id": 52,
                            "group-code": "REACTION",
                            "dict-value-code": "SAOYANG",
                            "dict-value-name": "瘙痒",
                            "dict-value-sort": 4
                        },
                        {
                            "show": false,
                            "value-id": 57,
                            "parent-id": 52,
                            "group-code": "REACTION",
                            "dict-value-code": "HUODONGSHOUXIAN",
                            "dict-value-name": "活动受限",
                            "dict-value-sort": 5
                        }
                    ],
                    "dict-key-id": 52,
                    "dict-key-code": "JU-BU-FAN-YING",
                    "dict-key-name": "局部反应",
                    "dict-key-sort": 1
                },
                {
                    "list": [
                        {
                            "show": false,
                            "value-id": 59,
                            "parent-id": 58,
                            "group-code": "REACTION",
                            "dict-value-code": "FARE",
                            "dict-value-name": "发热",
                            "dict-value-sort": 1
                        },
                        {
                            "show": false,
                            "value-id": 60,
                            "parent-id": 58,
                            "group-code": "REACTION",
                            "dict-value-code": "PIJUAN",
                            "dict-value-name": "疲倦",
                            "dict-value-sort": 2
                        },
                        {
                            "show": true,
                            "value-id": 61,
                            "parent-id": 58,
                            "group-code": "REACTION",
                            "dict-value-code": "GUANJIETONG",
                            "dict-value-name": "关节痛",
                            "dict-value-sort": 3
                        }
                    ],
                    "dict-key-id": 58,
                    "dict-key-code": "FEI-TE-YI-XING-FAN-YING",
                    "dict-key-name": "全身非特异性反应",
                    "dict-key-sort": 2
                },
                {
                    "list": [
                        {
                            "show": true,
                            "value-id": 63,
                            "parent-id": 62,
                            "group-code": "REACTION",
                            "dict-value-code": "CHUANXI",
                            "dict-value-name": "喘息",
                            "dict-value-sort": 1
                        },
                        {
                            "show": true,
                            "value-id": 64,
                            "parent-id": 62,
                            "group-code": "REACTION",
                            "dict-value-code": "KESOU",
                            "dict-value-name": "咳嗽",
                            "dict-value-sort": 2
                        },
                        {
                            "show": false,
                            "value-id": 65,
                            "parent-id": 62,
                            "group-code": "REACTION",
                            "dict-value-code": "XIONGMEN",
                            "dict-value-name": "胸闷",
                            "dict-value-sort": 3
                        },
                        {
                            "show": false,
                            "value-id": 66,
                            "parent-id": 62,
                            "group-code": "REACTION",
                            "dict-value-code": "QIBI",
                            "dict-value-name": "憋气",
                            "dict-value-sort": 4
                        },
                        {
                            "show": false,
                            "value-id": 67,
                            "parent-id": 62,
                            "group-code": "REACTION",
                            "dict-value-code": "YANYANGBUSHI",
                            "dict-value-name": "咽痒不适",
                            "dict-value-sort": 5
                        }
                    ],
                    "dict-key-id": 62,
                    "dict-key-code": "XIAOCHUANZHENGZHUANG",
                    "dict-key-name": "哮喘症状",
                    "dict-key-sort": 3
                },
                {
                    "list": [
                        {
                            "show": false,
                            "value-id": 69,
                            "parent-id": 68,
                            "group-code": "REACTION",
                            "dict-value-code": "BIYANG",
                            "dict-value-name": "鼻痒",
                            "dict-value-sort": 1
                        },
                        {
                            "show": false,
                            "value-id": 70,
                            "parent-id": 68,
                            "group-code": "REACTION",
                            "dict-value-code": "PENGTI",
                            "dict-value-name": "喷嚏",
                            "dict-value-sort": 2
                        },
                        {
                            "show": false,
                            "value-id": 71,
                            "parent-id": 68,
                            "group-code": "REACTION",
                            "dict-value-code": "LIUTI",
                            "dict-value-name": "流涕",
                            "dict-value-sort": 4
                        },
                        {
                            "show": false,
                            "value-id": 72,
                            "parent-id": 68,
                            "group-code": "REACTION",
                            "dict-value-code": "BISAI",
                            "dict-value-name": "鼻塞",
                            "dict-value-sort": 5
                        },
                        {
                            "show": false,
                            "value-id": 73,
                            "parent-id": 68,
                            "group-code": "REACTION",
                            "dict-value-code": "BIGAN",
                            "dict-value-name": "鼻干",
                            "dict-value-sort": 6
                        }
                    ],
                    "dict-key-id": 68,
                    "dict-key-code": "BI-YAN-ZHENG-ZHUANG",
                    "dict-key-name": "鼻炎症状",
                    "dict-key-sort": 4
                },
                {
                    "list": [
                        {
                            "show": false,
                            "value-id": 75,
                            "parent-id": 74,
                            "group-code": "REACTION",
                            "dict-value-code": "YANYANG",
                            "dict-value-name": "眼痒",
                            "dict-value-sort": 1
                        },
                        {
                            "show": false,
                            "value-id": 76,
                            "parent-id": 74,
                            "group-code": "REACTION",
                            "dict-value-code": "LIULEI",
                            "dict-value-name": "流泪",
                            "dict-value-sort": 2
                        },
                        {
                            "show": false,
                            "value-id": 77,
                            "parent-id": 74,
                            "group-code": "REACTION",
                            "dict-value-code": "JIEMOCHONGXUE",
                            "dict-value-name": "结膜充血",
                            "dict-value-sort": 3
                        },
                        {
                            "show": false,
                            "value-id": 78,
                            "parent-id": 74,
                            "group-code": "REACTION",
                            "dict-value-code": "WEIGUANG",
                            "dict-value-name": "畏光",
                            "dict-value-sort": 4
                        },
                        {
                            "show": false,
                            "value-id": 79,
                            "parent-id": 74,
                            "group-code": "REACTION",
                            "dict-value-code": "YANZHONG",
                            "dict-value-name": "眼肿",
                            "dict-value-sort": 5
                        }
                    ],
                    "dict-key-id": 74,
                    "dict-key-code": "GUO-MIN-XING-JIE-MO-YAN",
                    "dict-key-name": "过敏性结膜炎症状",
                    "dict-key-sort": 5
                },
            ]
        }
    

    处理函数:

    (let [detail (db/get-reaction-detail {:id id})
            reaction (j/read-json (:reaction detail))
            selected-reac (transform [ALL :list] (fn [e]
                                                   (let [t (filter #(true? (:show %)) e)]
                                                     (string/join "/" (map :dict-value-name t)))
                                                   ) reaction)]
        (assoc detail :reaction selected-reac))
    

    处理结果:

    "reaction": [
          {
            "list": "手臂肿胀/热/瘙痒",
            "dict-key-id": 52,
            "dict-key-code": "JU-BU-FAN-YING",
            "dict-key-name": "局部反应",
            "dict-key-sort": 1
          },
          {
            "list": "",
            "dict-key-id": 58,
            "dict-key-code": "FEI-TE-YI-XING-FAN-YING",
            "dict-key-name": "全身非特异性反应",
            "dict-key-sort": 2
          },
          {
            "list": "喘息/咳嗽",
            "dict-key-id": 62,
            "dict-key-code": "XIAOCHUANZHENGZHUANG",
            "dict-key-name": "哮喘症状",
            "dict-key-sort": 3
          },
          {
            "list": "",
            "dict-key-id": 68,
            "dict-key-code": "BI-YAN-ZHENG-ZHUANG",
            "dict-key-name": "鼻炎症状",
            "dict-key-sort": 4
          },
          {
            "list": "",
            "dict-key-id": 74,
            "dict-key-code": "GUO-MIN-XING-JIE-MO-YAN",
            "dict-key-name": "过敏性结膜炎症状",
            "dict-key-sort": 5
          },
          {
            "list": "血管性水肿",
            "dict-key-id": 80,
            "dict-key-code": "GUO-MIN-XING-PI-FU",
            "dict-key-name": "过敏性皮肤症状",
            "dict-key-sort": 6
          }
        ]
    

    6、

    相关文章

      网友评论

          本文标题:clojure爬坑之项目里处理过的复杂逻辑

          本文链接:https://www.haomeiwen.com/subject/mrsoxctx.html