Clojure - 将平面地图转换为具有预先确定的结构的嵌套

Jos*_*ien 1 transformation clojure hashmap

我是 clojure 的新手,我正在尝试将特定格式的消息转换为另一种格式。

即,我必须转换如下内容:

   {
     :image-url         ["https://image.png"],
     :topic             "Some title",
     :id                "88ebaf91-a01d-4683-9aa7-629bb3ecea01",
     :short-description "Some Description",
     :mobile-deeplink   "https://deeplink.com/link",
     :partner-name      "partner"}
  
Run Code Online (Sandbox Code Playgroud)

进入类似的东西

{
 :title   "Some title",
 :id      "88ebaf91-a01d-4683-9aa7-629bb3ecea01",
 :content {
           :url         ["https://image.png"],
           :description "Some Description",
           :deeplink    "https://deeplink.com/link",
           :partner     "partner"}}
Run Code Online (Sandbox Code Playgroud)

所以实际上,有重命名键和嵌套平面地图的组合

到目前为止我所做的事情大致如下:

(let [message-map {
                   :image-url         :purl
                   :topic             :title
                   :partner-name      :partner
                   :short-description :description
                   :mobile-deeplink   :deeplink}]
  (defn- map-to-body
    [message]
    (-> message
        (clojure.set/rename-keys message-map)
        ;;some sort of (assoc-in) <- this is where i need help in
    )))
Run Code Online (Sandbox Code Playgroud)

Bip*_*ill 5

组合assoc-in,一个路径转换表,reduce可以更具自描述性和可维护性。您可以选择减少转换表或输入消息,选择对您拥有的数据更有意义的一个。

(defn transform [m]
  (let [pp '([:image-url [:content :url]]
             [:topic [:title]]
             [:id [:id]]
             [:short-description [:content :description]]
             ;; etc.
             )]
    (reduce
     (fn [o [mk ok]]
       (assoc-in o ok (get m mk)))
     {}
     pp)))
Run Code Online (Sandbox Code Playgroud)