【问题标题】:Are the head and tail of a Set guaranteed to be mutually exclusive?Set 的头部和尾部是否保证互斥?
【发布时间】:2014-06-27 19:19:33
【问题描述】:

documentation 表示 Set.head 返回“第一个”项目,.tail 返回“除了第一个”之外的所有项目。* 由于 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 并返回以在每次递归时分离头尾要好。


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

【问题讨论】:

    标签: scala recursion scala-collections


    【解决方案1】:

    我对此不是 100% 确定,因为我没有过多关注实现,但是对于任何 HashSet,都有一个基于 hashCodeInt 类型)的隐式排序Set 中已经存在的值。

    这意味着对于任何Set 实例,对headtail 的调用将遵循该顺序,因此它不会是相同的元素。更重要的是,通过给定 Set 实例的元素的连续迭代应该以相同的顺序产生元素,因为 Set 是不可变的。

    要点是,虽然顺序未知,但任何情况下都有一个,一旦您向Set 添加(可变或不可变)新元素,它可能会立即改变。

    【讨论】:

      【解决方案2】:

      Set 上依赖headtail(没有排序)充其量是有风险的。

      在您的情况下,只需先从您的Set 获取IteratortheSet.toIterator,然后递归迭代器。当然,迭代器保证第一个元素与其他元素不同。

      【讨论】:

      • .tail 对应的 Iterator 是什么? .toSet 在调用.next 之后?
      【解决方案3】:

      你可以这样做:

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

      这样可以保证它们相互排斥。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多