Clojure:是否有一种方法可以删除键但保留其值



我需要一些帮助。我有下面的地图

(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)))

相关内容

  • 没有找到相关文章

最新更新