问题 套装的头部和尾部是否保证相互排斥?


文件 说 Set.head 返回“第一个”项,和 .tail 返回“除了第一个之外的所有”。*因为a Set 没有真正的“第一”项目,文档警告说,如果没有有序类型,您可能会在不同的运行中获得不同的结果。但你保证尾巴不包括头部吗?

我问的原因是我想知道是否可以降低一个 Set 喜欢这个:

def recurse(itemsToExamine: Set[Item], acc: Result): Result =
  if (itemsToExamine.isEmpty) acc
  else {
    val item = itemsToExamine.head
    recurse(
      item.spawnMoreItems ++ itemsToExamine.tail,
      acc.updatedFor(item))
  }

如果这是合法的,它肯定比转换更好 Set 至 Seq 并且返回以便在每次递归时分离头部和尾部。


*实际上,它说“选择第一项”和“选择除第一项之外的所有项目”。我认为“选择”只是一个糟糕的选择。如果有理由说“选择”而不是“退货”,请告诉我。


10257
2018-06-27 19:19


起源



答案:


依靠 head 和 tail 上 Set (没有订购)充其量是冒险的。

在你的情况下,只需得到一个 Iterator 从你的 Set 先用 theSet.toIterator,然后递归迭代器。当然,迭代器保证第一个元素与其他元素不同。


4
2018-06-27 19:43



什么相当于 .tail 为 Iterator? .toSet 打电话后 .next? - Ben Kovitz


答案:


依靠 head 和 tail 上 Set (没有订购)充其量是冒险的。

在你的情况下,只需得到一个 Iterator 从你的 Set 先用 theSet.toIterator,然后递归迭代器。当然,迭代器保证第一个元素与其他元素不同。


4
2018-06-27 19:43



什么相当于 .tail 为 Iterator? .toSet 打电话后 .next? - Ben Kovitz


我对这一点并不是100%肯定,因为我没有太多关注实现,但对于任何实现 HashSet 有一个隐含的顺序基于 hashCode (类型 Int)已经存在的值 Set

这意味着任何 Set 例如,打电话给 head 和 tail 会尊重这种排序,所以它不会是相同的元素。更重要的是,通过给定的元素连续迭代 Set 实例应该以相同的顺序生成元素,因为 Set 是不可改变的。

需要注意的是,虽然排序是未知的,但是对于任何实例都有一个,当你将一个新元素添加(可变或不可变)时,它可能会改变。 Set


4
2018-06-27 19:30





你可以这样做:

val set = Set(1, 2, 3)
val head = set.head
val tail = set - head

这保证了它们相互排斥。


3
2017-10-14 18:30