0

我正在使用 Scala 2.9 处理一些 Excel 文件。它们都存储在一个目录中并具有文件名Sales_yyyy_mm.xlsx

File我编写了以下代码,以生成一个包含年、月和每个 Excel的数组:

val fileStruct = """Sales_(\d\d\d\d)_(\d\d).xlsx""".r

val excels = (new java.io.File(dirName)).listFiles

val files = for(file <- excels; fileStruct(year, month) <- file.getName)
            yield(file, year, month)

文件数组正确计算为excels. 然而files是空的。我检查了文件名,它们都与正则表达式匹配(如果我使用match/重写我的代码case没有问题)。

代码可以正确编译,并且可以按照我的预期推断类型,但它不起作用。我究竟做错了什么?

4

3 回答 3

4

问题是file.GetName返回一个String-- 或者,从理解的角度来看,一个Seq[Char]. 现在,当您在 for comprehension 中使用模式匹配时,您是在映射或 flatMapping 之前应用过滤器。实际上,您正在这样做:

  val files = excels.flatMap(
    (file => file.getName().withFilter(
      ((x$0 => x$0 match {
        case fileStruct((year @ _), (month @ _)) => true
        case _ => false
      })).map(
        (x$1 => x$1 match {
         case fileStruct((year @ _), (month @ _)) => (file, year, month)
      }))))

问题是它x$0是 a Char,所以它永远不会匹配正则表达式模式。

于 2013-02-08T23:15:11.443 回答
2

我通过以下方式使其工作:

val fileStruct = """Sales_(\d\d\d\d)_(\d\d).xlsx""".r

val excels = (new java.io.File(dirName)).listFiles

val files = for{
                file <- excels
                year :: month :: _ <- fileStruct.unapplySeq(file.getName)
            }
            yield(file, year, month)
于 2013-02-09T07:49:48.097 回答
1

如果您的目录中只有 Sales_yyyy_mm_xlsx,请尝试以下操作:

scala> val files = for(file <- excels ; val fileStruct(year, month) = file.getName)
     | yield(file, year, month);

如果不 :

excels.map(file => fileStruct.findFirstIn(file.getName) match {
     |  case Some(fileStruct(year, month)) => Some(file, year, month)
     |  case _ => None
     | }).filterNot(_.isEmpty)

给我吗 :

res3: Array[Option[(java.io.File, String, String)]] = Array(Some((./Sales_2012_03.xlsx,2012,03)), Some((./Sales_2012_04.xlsx,2012,04)))

我认为当正则表达式不匹配时会出现问题

于 2013-02-08T23:05:54.257 回答