繁体   English   中英

为什么F#的默认集合集合是在C#的时候排序的?

[英]Why F#'s default set collection is sorted while C#'s isn't?

当从C#世界迁移到F#(最可能的惯用语)时,我发现了这个有趣的区别。

在C#的OOP&mutable世界中,默认的set集合似乎是HashSet ,它似乎没有默认排序(因为它接受的比较器只是为了相等); 如果你想要一个排序的,你必须使用SortedSet

但是在F#的世界中,基本set已经被排序,因为它需要用于实现相等比较的元素类型。 有什么具体的原因吗? 为什么不在这个语言的主要集合中设置无序集?

作为旁注,我想知道是否有可能有一个不允许重复的集合集合,但是当将某些元素作为重复元素丢弃时,它优先于某些元素。 示例:记录{ Name: string; Flag: Option<unit> } { Name: string; Flag: Option<unit> }以便在插入{ Name = "foo"; Flag = None } { Name = "foo"; Flag = None }以后{ Name = "foo"; Flag = Some() } { Name = "foo"; Flag = Some() }它最终只包含后一个元素(因为Flag存在)。

F# Set碰巧被排序,但它更多的是由于选择底层数据结构而产生的实现细节,通常不应该依赖它。

F#集和映射基于AVL树的变体,并且该结构恰好保持对存储在树中的元素进行排序的不变量。 它需要比较约束的原因是因为此树结构中的查找依赖于元素之间的直接比较来选择遍历的子树。

然而,这些结构的卖点是它们可以用来实现合理有效,不可变的地图版本和廉价设置,而这正是F#在更广泛的.NET平台没有提供任何替代方案时所需要的。

请注意,这不是此上下文中唯一可行的选择,并且像Clojure或Scala这样的JVM函数语言选择了不同的数据结构作为其映射的基础 - 散列数组映射trie - 这也是不可变和持久的,可能实现起来更复杂,对于较大的集合大小,可以说更有效,但恰好存储无序的元素。 与AVL树不同,树的遍历基于哈希,因此不需要比较约束。

因此,如果您已经知道优先级是不变的,那么排序集实际上比未排序集更容易实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM