请在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等。大多数使用单个key-path并留下空集合 - 这些似乎主要来自孵化器版本。Encore版本通过将key path与要删除的最后叶子键分开来使用多个路径(变长)。Medley、useful和plumbing版本仅对映射进行操作并删除空映射。

我想象不出,我们会在核心中制作一个特定于map的版本(因为其他-in函数是通用的),因此我得出结论,我们需要一个可以留下空集合的dissoc-in。鉴于这一点,我不确定dissoc-in相对于update-in + dissoc提供的价值是否足够,以至于值得在此阶段添加到核心中,特别是既然它存在于各种实用程序库中(在许多情况下具有不同的语义)。那么,我们可能会破坏(或者至少会打扰)许多现有dissoc-in impls的用户。我将对此保持开放,但我倾向于在此阶段拒绝此增强功能。

+1

评论者:alexmiller

是的,尽管我认为在更新情况下,这些因素平衡方式不同。在更新中,实现方案更少,并且它们与我们提出的添加方案相匹配。因此,它们创造了用核心功能替换现有功能的潜力。

我认为常用的实用库实现(flatland/useful/plumbing)实际上是覆盖了一个不同的需求——仅在映射上执行更新-in、dissoc和路径删除。所以,如果目标是覆盖通用用途,那么我们就需要让它仅在映射上工作,并删除留下的空路径。然而,我认为这与其他核心-in函数有些矛盾。我想也许有一个折衷方案来做路径删除,但使其作用于映射之外——这将满足实用库的需求,同时也像其他-in函数那样具有通用性。如果您需要留下空集合,您可以这样做——update-in+dissoc。

0

由:jafingerhut 发表的评论

日期为 Sep 13 2012 的补丁 clj-1063-add-dissoc-in-patch-v2.txt 取代了 2012年9月7日的 001-dissoc-in.diff。它修复了一个拼写错误(丢失文档字符串中的末尾 "),并添加了一个用于新函数的测试用例。

0

由:bronsa 发表的评论

感谢修复你的问题,Andy

0

由:jafingerhut 发表的评论

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

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

0
_由:bronsa 发表的评论_

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

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

而此补丁中的那个不会(正如我所预期的那样)

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

由:stu 发表的评论

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

0
by

评论人:andrewhr

保留空路径真的是最期望的做法吗?我认为,鉴于两者 {{assoc-in}} / {{update-in}} 在路上都会创建路径,这种行为看起来更像是一种“双关”。

哪种坏事情可能发生,{{nil}} 万岁处理不好?这些问题对于 {{dissoc-in}} 用户的观点来说过于模糊不清了吗?

0
by

评论者:alexmiller

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

0
by
_评论人:[email protected]_

正在测试 "clj-1063-add-dissoc-in-patch-v2.txt"


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


这种行为非常出乎意料。虽然孵化器版本没有这个问题,但它确实会删除空映射。

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

评论人:[email protected]

@alex,您希望保留空路径还是删除?两种方式都可以接受,尽管权衡之下,我稍微偏向于留在原处。一旦我知道您的方向,我就可以为这项工作编写测试。

0
by

评论者:alexmiller

一个是另一个的权衡是什么?

在人们使用 dissoc-in 替体(如具有 dissoc 的 update-in)的地方,他们期望的行为是什么?

0
by
_评论人:michalmarczyk_

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

然而,如果我们想在这个过程中承认向量,那么保留空路径在那种情况下会具有很清晰的语义。


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


相比之下,移除空路径可能会导致需要解决的问题,这些问题可能必须通过限制移除路径的行为仅限于映射或当嵌套在向量中的子路径成为条目时抛出异常来解决。任何一种方法似乎都不太理想。
0

评论者:michalmarczyk

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

0

由:bronsa 发表的评论

可以为 update 提出相同的论点。实际上,updatedissoc-in 可能在几个实用库中找到,这应该表明人们 并不乐意仅仅使用 update-in + dissoc

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

...