在 cond-> 中分离哈希映射向量中的键
dissoc a key in a vector of hashmaps in a cond->
如何删除 cond-> 中的 :z of data ?
(def data
{:a [{:x 1
:y 2
:z "remove this"}
{:x 3
:y 4
:z 5}]
:b "b"
:c "c"})
我怀疑我必须使用更新,但我一直没有成功。
(cond-> data
:a (#(<function to remove :z when :z is "remove this">))
:b (dissoc :b))
我目前的理论是使用更新、映射和 if 语句。不过,我一直无法找到有效的确切语法
(cond-> data
:a (#(update-in (:a %) [:z]
(map (fn [A]
(if (= (:z A) "remove this")
(dissoc A :z)
A))
(:a %))))
:b (dissoc :b))
=> ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.IFn clojure.core/apply (core.clj:652)
您的尝试非常接近:
您似乎确实两次导航“进入”地图。如果你想改变那个地图中:a
的项目,那么update
就足够了。此外,您不必通过 :z
路径,因为这是您想要从地图 dissoc
路径。
所以我的建议是:
(cond-> data
:a (update :a
(partial mapv #(if (= (:z %) "remove this") (dissoc % :z) %)))
:b (dissoc :b))
update
因为我们只改变顶层
- 记住,
update
的第一个参数来自 cond->
mapv
保持向量
- 传递给
update
的函数的第一个参数将是 (:a data)
,但是 mapv
将其作为最后一个参数 - 所以在这里使用 partial
- 这让我们可以选择使用函数文字作为映射函数(记住,没有函数文字的嵌套);当然这个函数是一个候选提取到它自己的函数
也许您还想看看 specter:
(require '[com.rpl.specter :refer [ALL NONE setval]])
(cond->> data
:a (setval [:a ALL :z #{"remove this"}] NONE)
:b (setval :b NONE))
;;=> {:a [{:x 1, :y 2} {:x 3, :y 4, :z 5}], :c "c"}
我会稍微分解一个问题,所以你分阶段处理数据。使用我的 favorite template project,我们得到以下内容:
(ns tst.demo.core
(:use tupelo.core tupelo.test))
(dotest
(let [data {:a [{:x 1
:y 2
:z "remove this"}
{:x 3
:y 4
:z 5}]
:b "b"
:c "c"}
result (update data :a
(fn [vec-of-maps]
(mapv #(dissoc % :z) vec-of-maps)))]
(is= result
{:a [{:x 1 :y 2}
{:x 3 :y 4}]
:b "b"
:c "c"})))
如果需要,您可以单独 dissoc
:b
。
如何删除 cond-> 中的 :z of data ?
(def data
{:a [{:x 1
:y 2
:z "remove this"}
{:x 3
:y 4
:z 5}]
:b "b"
:c "c"})
我怀疑我必须使用更新,但我一直没有成功。
(cond-> data
:a (#(<function to remove :z when :z is "remove this">))
:b (dissoc :b))
我目前的理论是使用更新、映射和 if 语句。不过,我一直无法找到有效的确切语法
(cond-> data
:a (#(update-in (:a %) [:z]
(map (fn [A]
(if (= (:z A) "remove this")
(dissoc A :z)
A))
(:a %))))
:b (dissoc :b))
=> ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.IFn clojure.core/apply (core.clj:652)
您的尝试非常接近:
您似乎确实两次导航“进入”地图。如果你想改变那个地图中:a
的项目,那么update
就足够了。此外,您不必通过 :z
路径,因为这是您想要从地图 dissoc
路径。
所以我的建议是:
(cond-> data
:a (update :a
(partial mapv #(if (= (:z %) "remove this") (dissoc % :z) %)))
:b (dissoc :b))
update
因为我们只改变顶层- 记住,
update
的第一个参数来自cond->
mapv
保持向量- 传递给
update
的函数的第一个参数将是(:a data)
,但是mapv
将其作为最后一个参数 - 所以在这里使用partial
- 这让我们可以选择使用函数文字作为映射函数(记住,没有函数文字的嵌套);当然这个函数是一个候选提取到它自己的函数
也许您还想看看 specter:
(require '[com.rpl.specter :refer [ALL NONE setval]])
(cond->> data
:a (setval [:a ALL :z #{"remove this"}] NONE)
:b (setval :b NONE))
;;=> {:a [{:x 1, :y 2} {:x 3, :y 4, :z 5}], :c "c"}
我会稍微分解一个问题,所以你分阶段处理数据。使用我的 favorite template project,我们得到以下内容:
(ns tst.demo.core
(:use tupelo.core tupelo.test))
(dotest
(let [data {:a [{:x 1
:y 2
:z "remove this"}
{:x 3
:y 4
:z 5}]
:b "b"
:c "c"}
result (update data :a
(fn [vec-of-maps]
(mapv #(dissoc % :z) vec-of-maps)))]
(is= result
{:a [{:x 1 :y 2}
{:x 3 :y 4}]
:b "b"
:c "c"})))
如果需要,您可以单独 dissoc
:b
。