请在2024年Clojure调查!中分享您的想法。

欢迎!有关如何使用本站的一些更多信息,请参阅关于页面。

+5
Clojure

尽管有assoc-in,但没有clojure.core/dissoc-in。
确实可以通过update-in和dissoc构建dissoc-in,但这也是对assoc-in的一个反对意见。
当提供一个assoc-in的快捷方式时,也应提供dissoc-in的快捷方式,以保持一致性。
实现方式类似于assoc-in。

16 答案

+1

评论由:alexmiller发表

我们必须考虑向量或除了映射之外的其他关联数据结构。我也希望不要有标志,而是保持它为变长以删除多个。

使用类似下面的方法

(update-in [{:foo 1}] [0] dissoc :foo)

我们将得到{{[{}]}},因此现有的方法确实留下了空集合。

我还查看了一些现有的dissoc-in实现(例如core.incubator、taoensso.encore、clj-http、medley、useful、plumbing等)。大多数使用单个键路径并与空集合一起工作——这些似乎主要源自incubator版本。Encore使用多个路径通过分离键路径和要删除的最终叶子键来处理变长。Medley、Useful和Plumbing仅限于使用映射,并删除空映射。

我无法想象我们会制作一个只针对map的特定版本(因为所有的-in函数都是通用的),因此我得出结论,我们可能需要一个允许空集合的dissoc-in。鉴于这一点,我不确定dissoc-in相对于update-in + dissoc提供了多少价值,值得我们在此阶段添加到核心中,特别是在它存在于各种实用库中(在许多情况下语义不同)。我们可能打破了(或至少不便了)许多现有dissoc-in实现的用户。我将对此进行评论,但我倾向于在此阶段不采取此增强措施。

+1
已回答 by

评论由:alexmiller发表

是的,尽管我认为在更新情况下,这些因素平衡得不同。在更新中,实施得较少,并且它们与我们提议添加的内容匹配。因此,它们为用核心功能替换现有内容创造了可能性。

我认为常见的实用程序库实现(flatland/useful/plumbing)实际上覆盖了一个不同的需求——只在地图上实现update-in、dissoc和路径删除。所以,如果目标是覆盖常见的用法,那么我们可能需要在地图上工作并删除留下的空路径。然而,我认为这与其他核心-in函数有些矛盾。我想可能有一个折衷方案来做路径删除,但使其超越地图——这会满足实用程序库所示的需求,同时也像其他-in函数那样通用。如果您需要留下空集合,您现在可以像现在那样做 - update-in+dissoc。

0
by

评论者:jafingerhut

2012年9月13日的补丁clj-1063-add-dissoc-in-patch-v2.txt取代了2012年9月7日的001-dissoc-in.diff。它修复了一个错别字(文档字符串中缺少最后的"),并为其添加了一个测试案例。

0
by

评论者:bronsa

感谢您的修复,Andy

0
by

评论者:jafingerhut

这个建议的dissoc-in应该与clojure.core.incubator中的版本进行比较,我偶然遇到了。我看它们看起来不同,但还没有检查它们是否有任何行为差异。

https://github.com/clojure/core.incubator/blob/master/src/main/clojure/clojure/core/incubator.clj

0
by
_评论者:bronsa_

clojure.core.incubator中的dissoc-in递归删除空映射

user=> (clojure.core.incubator/dissoc-in {:a {:b {:c 1}}} [:a :b :c])
{}

尽管在这个过程中我没有预计到(可能是我的期望值)

用户=> (dissoc-in {:a {:b {:c 1}}} [:a :b :c])
{:a {:b {}}}
0

评论者:stu

请在孵化器中完成这项工作。

0

评论者:andrewhr

保留空的路径真的是最受欢迎的做法吗?我认为,因为{{assoc-in}}/{{update-in}}在过程中创建路径,这一行为看起来像是真正的“双复制”。

什么样的坏情况会导致{{nil}}在纠缠中处理得不好?这些问题对于{{dissoc-in}}用户来说是过于模糊的吗?

0

评论由:alexmiller发表

补丁中的测试过于简单。应该测试多级、记录、向量等。

0
_评论者:[email protected]_

测试“clj-1063-add-dissoc-in-patch-v2.txt”


(dissoc-in {} [:a :b :c])
=> {:a {:b nil}}


这种行为相当令人意外。尽管孵化器版本没有这个问题,但它确实删除了空映射。

我正在为这个补丁编写测试(以及可能的新dissoc-in),但我还不清楚是否应该保留或删除空路径?我不介意哪种方式,尽管我倾向于同意Andrew Rosa的观点,即保留它们更对称。
0

评论者:[email protected]

@alex,你希望保留空路径还是删除它们?两种方式都可以接受,尽管权衡之下我略微更倾向于保留它们。一旦我知道你想走哪个方向,我可以为这个编写测试。

0

评论由:alexmiller发表

两者之间的权衡是什么?

在人们使用dissoc-in代理(update-in with dissoc等)的地方,他们期望的行为是什么?

0
_评论人:michalmarczyk_

如果我们只想处理嵌套在嵌套映射中的映射,我想我可能更喜欢删除空子路径。

然而,如果我们希望在途中接受向量,那么保留空路径在这个情况下会使语义更加清晰。


(dissoc-in [{:foo 1}] [0 :foo])
;= [{}]


相比之下,删除空路径似乎会导致问题,这些问题必须通过限制删除路径的行为仅限于映射或当子路径在向量中变为条目时抛出异常来解决。两种方法似乎都不是最优的。
0

评论人:michalmarczyk

此外,我们可以从技术上接受一个标志来决定是否应删除空路径,并让用户确保只有在没有向量的情况下才传递{{true}}。尽管如此,我不太喜欢这种方法,因为它似乎让我觉得额外参数的更自然用途是为了提供额外的路径以匹配变异性{{dissoc}}和{{dissoc-in}}语义(参见CLJ-1771)。

0

评论者:bronsa

同样的论点也可以适用于包括update。事实上,updatedissoc-in可以在多个实用库中找到,这应该表明人们并不满足于只使用update-in + dissoc

当然,将其添加到核心中将在使用某些库时引发警告(它不会破坏任何东西,导致与update断开的AOT错误已经被修复),但我认为这不是什么大问题;新版本的这些库将很快发布,即使不是这样,警告也不是世界末日。

...