我需要一些帮助。我有下面的地图
(def my-list
{:data-0
{:a1 ;;this is the value for :ward-room
{:type "Specialist"
:name "Dr Spongebob"
:illness "dehydration"
:ward-room "a1"}}
:data-1
{:b5
{:type "GP"
:name "Dr Patrick"
:illness "fishy eyes"}
:ward-room "b5"}})
我想把它转换成如下图
(def my-new-list
{:data-0
{:type "Specialist"
:name "Dr Spongebob"
:illness "dehydration"
:ward-room "a1"}
:data-1
{:type "GP"
:name "Dr Patrick"
:illness "fishy eyes"}
:ward-room "b5"}})
我不知道如何做到这一点,所以我尝试使用seq
,然后flatten
,但没有成功。我不太确定如何开始解决这个问题。如果你能帮点忙,我会很感激的。
考虑更正结构,:ward-room
对两个条目具有相同的嵌套级别:
(def my-list
{:data-0
{:a1 ;;this is the value for :ward-room
{:type "Specialist"
:name "Dr Spongebob"
:illness "dehydration"
:ward-room "a1"}}
:data-1
{:b5
{:type "GP"
:name "Dr Patrick"
:illness "fishy eyes"
:ward-room "b5"}}})
有一些选项:
首先你可以使用reduce-kv
,重新映射到新的值:
(reduce-kv
(fn [acc k v] (assoc acc k (val (first v))))
{}
my-list)
;; {:data-0
;; {:type "Specialist",
;; :name "Dr Spongebob",
;; :illness "dehydration",
;; :ward-room "a1"},
;; :data-1
;; {:type "GP",
;; :name "Dr Patrick",
;; :illness "fishy eyes",
;; :ward-room "b5"}}
或者您可以使用zipmap
来压缩带有新值的密钥:
(zipmap (keys my-list)
(map (comp val first val) my-list))
也有一个很好的方法来实现功能组合:
(into {} (map (juxt key (comp val first val))) my-list)
另一种方法是在上层为每个内部映射拼接条目。这也适用于'畸形'数据,如您的:
(def my-list
{:data-0
{:a1 ;;this is the value for :ward-room
{:type "Specialist"
:name "Dr Spongebob"
:illness "dehydration"
:ward-room "a1"}}
:data-1
{:b5
{:type "GP"
:name "Dr Patrick"
:illness "fishy eyes"}
:ward-room "b5"}})
(defn lift-entries [old-entries]
(into {} (mapcat #(if (map? (val %))
(val %)
[%]))
old-entries))
(zipmap (keys my-list) (map lift-entries (vals my-list)))
;; {:data-0
;; {:type "Specialist",
;; :name "Dr Spongebob",
;; :illness "dehydration",
;; :ward-room "a1"},
;; :data-1
;; {:type "GP",
;; :name "Dr Patrick",
;; :illness "fishy eyes",
;; :ward-room "b5"}}
我认为你的数据样本有剪切/粘贴错误。下面是一个简单的答案:
(def my-data
{:data-0 {:a1 {:type "Specialist"
:name "Dr Spongebob"
:illness "dehydration"
:ward-room "a1"}}
:data-1 {:b5 {:type "GP"
:name "Dr Patrick"
:illness "fishy eyes"
:ward-room "b5"
}}})
(defn delete-intermediate-level
[data]
(into {}
(for [[k1 v1] data]
[k1 (into {}
(for [[k2 v2] v1]
v2))])))
与结果:
(delete-intermediate-level my-data) =>
{:data-0
{:type "Specialist",
:name "Dr Spongebob",
:illness "dehydration",
:ward-room "a1"},
:data-1
{:type "GP",
:name "Dr Patrick",
:illness "fishy eyes",
:ward-room "b5"}}
如果my-list
应该被定义为
(def my-list
{:data-0
{:a1 ;;this is the value for :ward-room
{:type "Specialist"
:name "Dr Spongebob"
:illness "dehydration"
:ward-room "a1"}}
:data-1
{:b5
{:type "GP"
:name "Dr Patrick"
:illness "fishy eyes"
:ward-room "b5"}}})
(也就是说,如果我们在:b5
映射中包含:ward-room
键和值,而不是让它在松散中浮动),那么我可以看到这样做的最快方法是:
(zipmap (keys my-list) (map #(first (vals %)) (vals my-list)))
如果我们用(pprint...)
格式包装上面的代码,它返回
{:data-0
{:type "Specialist",
:name "Dr Spongebob",
:illness "dehydration",
:ward-room "a1"},
:data-1
{:type "GP",
:name "Dr Patrick",
:illness "fishy eyes",
:ward-room "b5"}}
编辑
或者如果你喜欢线程最后的形式,你可以使用
(->> my-list
(vals)
(map #(first (vals %)))
(zipmap (keys my-list)))