请在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等。大多数使用一个键路径,并留下空集合——这看起来很大程度上源自孵化器版本。Encore版本通过将键路径与最终要移除的叶子键分开来处理多个路径(可变参数)。Medley,useful和plumbing版本只处理映射,并移除空的映射。

我无法想象我们会把这个版本专门针对映射的版本放在核心中(因为其他-in函数都是通用的),因此我得出结论,我们需要一个可以留下空集合的dissoc-in。考虑到这一点,我不确定dissoc-in目前与update-in + dissoc相比提供了多大的价值才值得添加到核心中,尤其是在它已经存在各种工具库中(有时语义不同)。这样我们可能会打破(或至少不方便)许多现有dissoc-in实现的使用者。我将此留作评论,但目前我倾向于不通过此增强。

+1

评论由:alexmiller发表

是的,但我认为在更新情况下这些因素平衡不同。在更新中,实现较少,并且它们与我们提出的添加内容相匹配。因此,他们创造了用核心功能替换现有内容的机会。

我认为通用的实用库实现(flatland/useful/plumbing)实际上是在满足一个不同需求——只在地图上进行更新-in、移除路径。因此,如果目标是覆盖常见的使用情况,那么我们就需要在地图上工作并移除留下的空路径。然而,我认为这与其他核心-in函数有些矛盾。我想可能有一个折衷的方案来实现路径移除,但使其在地图之外也能工作——这样既能满足实用库所指出的需求,又像其他-in函数一样具有通用性。如果您需要留下空的数据集,您现在可以像这样做:update-in+dissoc。

0

发表评论者:jafingerhut

日期为2012年9月13日的补丁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中的dissoc-in进行比较,我刚刚偶然发现了它。我看它们的看起来不同,但还没有检查是否有任何行为差异。

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])
{}

而本补丁中的dissoc-in没有这么做(正如我所预期的)

user=> (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替换项(如update-in中使用dissoc等)的地方,人们期望的行为是什么?

0
_评论者:michalmarczyk_

如果我们只想处理嵌套在映射中的映射……,我可能更倾向于移除空子路径。

然而,如果我们想沿途接受向量,那么保留空路径在这种情况下会显得语义更加清晰。


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


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

评论者:michalmarczyk

我们也可以从技术上接受一个标志来决定是否应该删除空路径,并让用户确保只在没有向量的情况下传递{{true}}。不过,我不太喜欢这个方法,因为这在我看来,额外的参数更为自然的目的是为了为dissoc提供更多的参数路径以匹配可变参数{{dissoc}}和{{dissoc-in}}的语义(参看CLJ-1771)。

0

发表评论者:bronsa

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

将此添加到核心中确实会导致使用某些库时出现警告(这不会破坏任何东西,导致与update断裂的AOT错误已修复),但我不认为这真正是个大问题;那些库的新版本将很快发布,即使不是这样,警告也不会是世界末日。

...