Clojure 从映射中删除键和值
我有一张这样的地图:Clojure 从映射中删除键和值,clojure,Clojure,我有一张这样的地图: {\a [\h] \h [\w \w] \i [\w \h \t] \p [\t \u \h \a] \s [\t \a \t \t \i \w \h] \t [\a] \u [\t \t \s] \w []} (into {} (map (fn [[k v]] [k (filterv #(not= \w %) v)])) (dissoc data \w)) 我想从键和值中删除例如。\w。i、 e.留下这个 {\a [\h]
{\a [\h]
\h [\w \w]
\i [\w \h \t]
\p [\t \u \h \a]
\s [\t \a \t \t \i \w \h]
\t [\a]
\u [\t \t \s]
\w []}
(into {}
(map (fn [[k v]] [k (filterv #(not= \w %) v)]))
(dissoc data \w))
我想从键和值中删除例如。\w。i、 e.留下这个
{\a [\h]
\h []
\i [\h \t]
\p [\t \u \h \a]
\s [\t \a \t \t \i \h]
\t [\a]
\u [\t \t \s]}
请注意,\w键已消失,\w已从所有值中消失
现在我有了这个,这是有效的,但我相信一定有更好的,更Clojurey的方法
(defn remove-last [last cmap]
(reduce-kv (fn [acc k v]
(if (empty? v)
acc
(into acc {k (vec (filter #(not= % last) v))}))) {} cmap))
要删除的键始终是空向量
我怎样才能做得更好呢?我觉得您的解决方案非常地道。这项要求很不寻常,我立即认为可以减少。你的电话是空的吗?但这不符合你的要求。您必须测试k键是否持续 另外,我不会在这里使用姓氏。它与已存在的名称冲突 一个非常类似的选择是
(defn remove-all-of [it m]
(reduce
(fn [acc [k v]]
(if (not= it k)
(assoc acc
k
(into (empty v)
(filter #(not= it %) v)))
acc))
{}
m))
这还允许您使用空v将向量以外的其他可排序内容作为值。我发现您的解决方案非常惯用。这项要求很不寻常,我立即认为可以减少。你的电话是空的吗?但这不符合你的要求。您必须测试k键是否持续 另外,我不会在这里使用姓氏。它与已存在的名称冲突 一个非常类似的选择是
(defn remove-all-of [it m]
(reduce
(fn [acc [k v]]
(if (not= it k)
(assoc acc
k
(into (empty v)
(filter #(not= it %) v)))
acc))
{}
m))
这也允许您通过使用空v将向量以外的其他可排序内容作为值。我非常喜欢specter:
(s/setval (s/walker (fn-> (= \w))) s/NONE {\a [\h]
\h [\w \w]
\i [\w \h \t]
\p [\t \u \h \a]
\s [\t \a \t \t \i \w \h]
\t [\a]
\u [\t \t \s]
\w []})
我非常喜欢斯佩克特:
(s/setval (s/walker (fn-> (= \w))) s/NONE {\a [\h]
\h [\w \w]
\i [\w \h \t]
\p [\t \u \h \a]
\s [\t \a \t \t \i \w \h]
\t [\a]
\u [\t \t \s]
\w []})
我的建议是,首先从映射中分解\w键,考虑到这是~恒定时间操作,然后使用转换器在一次过程中重塑序列,而不丢失声明样式,并消除reduce的冗长性,同时保持性能。可能是这样的:
{\a [\h]
\h [\w \w]
\i [\w \h \t]
\p [\t \u \h \a]
\s [\t \a \t \t \i \w \h]
\t [\a]
\u [\t \t \s]
\w []}
(into {}
(map (fn [[k v]] [k (filterv #(not= \w %) v)]))
(dissoc data \w))
至于我,我认为这比Reope/AsCOC或减少/更新
> P>更可读,我建议首先从图中分解W键,考虑这是恒定的时间操作,然后使用换能器在不丢失声明风格的情况下一次通过修改序列,并消除缩减的冗长。在保持性能的同时。可能是这样的:{\a [\h]
\h [\w \w]
\i [\w \h \t]
\p [\t \u \h \a]
\s [\t \a \t \t \i \w \h]
\t [\a]
\u [\t \t \s]
\w []}
(into {}
(map (fn [[k v]] [k (filterv #(not= \w %) v)]))
(dissoc data \w))
对我来说,我认为这比Re/AsCOC或减少/更新更可读,我会更新这个问题。我忘了添加要删除的密钥将始终有一个空向量!这是唯一一个vec为空的钥匙吗?如果是这样,您不必在示例中传递该键。是的,如果要删除的值为\x,则该键\x将始终为空,并且将是唯一的空向量。在这种情况下,您可以在地图上迭代一次以找到要删除的对象,然后第二次将其删除。取决于映射的大小以及您从调用方的角度对函数的偏好。次要说明:filter not=it%v可以写成remove{it}v for clarityOh,我将更新问题。我忘了添加要删除的密钥将始终有一个空向量!这是唯一一个vec为空的钥匙吗?如果是这样,您不必在示例中传递该键。是的,如果要删除的值为\x,则该键\x将始终为空,并且将是唯一的空向量。在这种情况下,您可以在地图上迭代一次以找到要删除的对象,然后第二次将其删除。取决于你的映射有多大,以及你从调用者的角度对函数的偏好。次要说明:filter not=it%v可以写为remove{it}v以清晰明了fn->语法是什么?@akond,Specter非常棒,但是这种情况太简单,很容易用惯用的clojure执行,因此特定的dsl不仅过时,但这也是自以为是的。尽管如此,specter在更复杂的数据查询/转换方面的好处是无可争议的。fn->语法是什么?@akond,specter非常棒,但这个案例太简单,很容易用惯用的clojure执行,因此特定的dsl不仅过时,而且有害。这是自以为是的:。尽管如此,specter对于更复杂的数据查询/转换的好处是无可争议的。