【问题标题】:Scala List of tuple becomes empty after for loopScala 元组列表在 for 循环后变为空
【发布时间】:2021-12-28 03:03:59
【问题描述】:

我有一个 Scala 元组列表,“params”,大小为 28。我想循环并打印列表的每个元素,但是没有打印任何内容。完成 for 循环后,我检查了列表的大小,现在变为 0。

我是 scala 的新手,经过长时间的谷歌搜索后我无法弄清楚。

val primes = List(11, 13, 17, 19, 2, 3, 5, 7)
val params = primes.combinations(2)
println(params.size)

for (param <- params) {
  print(param(0), param(1))
}
println(params.size)



【问题讨论】:

    标签: list scala tuples


    【解决方案1】:

    combinations List 中的方法创建一个Iterator。一旦使用size 之类的方法使用Iterator,它将为空。

    来自docs

    在对迭代器调用方法后,永远不要使用它。

    如果你注释掉println(params.size),你可以看到for循环正在打印出元素,但最后一个println(params.size)将保持为0。

    【讨论】:

    • 感谢您的解释。您知道如何保存组合方法的结果以供以后使用吗?
    • @HoaTrinh, combination(n).toList 将达到目的。但请记住,这只会创建一个List[List[Int]],而不是问题中提到的List[(Int, Int)]
    【解决方案2】:

    补充强尼的精彩回答:

    你知道如何保存组合方法的结果以供以后使用吗?

    好吧,正如已经建议的那样,您可以toList
    但是,请注意combinations 返回Iterator 是有原因的,因为数据可能太大,如果您可以接受,请继续;但你仍然可以利用懒惰。

    例如,让我们在收集结果之前将内部列表转换为元组:

    val params =
      primes
        .combinations(2)
        .collect {
          case a :: b :: Nil => (a, b)
        }.toList
    

    以同样的方式,您可以在执行toList之前在链中添加额外的步骤,例如另一个mapfilter
    更好的是,如果您的最终操作类似于foreach(foo),那么您甚至不需要将所有内容收集到List

    【讨论】:

      【解决方案3】:

      primes.combinations(2) 返回迭代器。

      迭代器是允许迭代一个序列的数据结构 元素。他们有一个 hasNext 方法来检查是否有下一个 元素可用,以及返回下一个元素的 next 方法 并从迭代器中丢弃它。

      所以,它就像指向 Iterable 集合的指针。完成迭代后,您将无法再进行迭代。

      println(params.size) 在计算size 时执行该时间迭代完成并且现在params 指向结束。因为这个for (param &lt;- params) 将等同于围绕空集合循环。

      有两种可能的解决方案:

      1. 不要在 for 循环之前检查大小。
      2. 将迭代器转换为可迭代,例如列表。 params = primes.combinations(2).toList

      要了解有关 Iterator 和 Iterable 的更多信息,请参阅 What is the relation between Iterable and Iterator?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多