【问题标题】:Why does my Scala list disappear in the following code?为什么我的 Scala 列表在以下代码中消失了?
【发布时间】:2011-08-21 13:57:28
【问题描述】:
val files = new File("data").list()
val filtered = files.filter(name => name.contains("txn"))
val masterList = new ListBuffer[String]
for (file <- filtered) {
  val lines = Source.fromFile(new File("data\\" + file), "UTF-16").getLines
  val cleaned = lines.filter(!masterList.contains(_))
  println("*" + cleaned.length)
  cleaned.foreach(println(_))
  println("**" + cleaned.length)
  cleaned.foreach(masterList.append(_))
}

代码输出如下

*175
**0

我不明白为什么我的列表消失了

【问题讨论】:

    标签: scala


    【解决方案1】:

    cleaned 是一个迭代器。

    scala> val cleaned = lines.filter(_!="")
    cleaned: Iterator[String] = non-empty iterator
    

    在分配之后它是非空的。 scala 中的迭代器是一次性使用的——一旦你遍历它(例如,通过应用length 方法),它就会变成空的:

    scala> cleaned.length
    res0: Int = 13
    
    scala> cleaned.length
    res1: Int = 0
    

    您可以通过转换为 List 或 Seq(惰性)来修复该行为:

    scala> val lines=Source.fromFile("bla.txt").getLines
    lines: Iterator[String] = non-empty iterator
    
    scala> val cleaned = lines.filter(_!="").toSeq
    cleaned: Seq[String] = Stream(first, ?)
    
    scala> cleaned.length
    res4: Int = 13
    
    scala> cleaned.length
    res5: Int = 13
    

    【讨论】:

    • 哇。这种行为让我措手不及。从未想过对length 的无害调用实际上会破坏整个事情!
    • 这是更好的词。 omn​​omnomnomm
    【解决方案2】:

    Source.fromFile(new File("data\\" + file), "UTF-16").getLines 返回一个Iterator[String]。过滤仍然返回Iterator。在迭代器上调用 length 将导致它被完全读取,直到 hasNext 返回 false。第二次,空了。类似于:

    scala> val cleaned = List(1,2).iterator
    cleaned: Iterator[Int] = non-empty iterator
    
    scala> cleaned.length
    res10: Int = 2
    
    scala> cleaned.length
    res11: Int = 0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-06
      • 1970-01-01
      • 2022-08-17
      • 2021-03-20
      • 2013-10-18
      • 1970-01-01
      相关资源
      最近更新 更多