Reputation: 8392
I am using Scala 2.9 to process some Excel files. They are all stored in a directory and have the filename Sales_yyyy_mm.xlsx
.
I wrote the following code, to produce an array with the year, month and File
of each 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)
The array of files is computed correctly into excels
. However files
is empty. I have checked the file names and they all match the regex (if I rewrite my code using match
/case
there is no problem).
The code compiles correctly and the types are inferred as I expect them, but it doesn't work. What am I doing wrong?
Upvotes: 0
Views: 477
Reputation: 8392
I made it work in the following way:
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)
Upvotes: 2
Reputation: 297205
The problem is that file.GetName
returns a String
-- or, from the for-comprehension's point of view, a Seq[Char]
. Now, when you use a pattern matching in a for comprehension, you are applying a filter before mapping or flatMapping. In effect, you are doing this:
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)
}))))
The problem is that x$0
is a Char
, so it will never match the regex pattern.
Upvotes: 4
Reputation: 1178
If you only have Sales_yyyy_mm_xlsx on your directory, try this :
scala> val files = for(file <- excels ; val fileStruct(year, month) = file.getName)
| yield(file, year, month);
and if not :
excels.map(file => fileStruct.findFirstIn(file.getName) match {
| case Some(fileStruct(year, month)) => Some(file, year, month)
| case _ => None
| }).filterNot(_.isEmpty)
give me :
res3: Array[Option[(java.io.File, String, String)]] = Array(Some((./Sales_2012_03.xlsx,2012,03)), Some((./Sales_2012_04.xlsx,2012,04)))
I think the problem appear when the regexp doesn't match
Upvotes: 1