0

I need to create a HashMap of directory-to-file in scala while I list all files in the directory. How can I achieve this in scala?

val directoryToFile = awsClient.listFiles(uploadPath).collect {
  case path if !path.endsWith("/") => {
    path match {
      // do some regex matching to get directory & file names
      case regex(dir, date) => {
          // NEED TO CREATE A HASH MAP OF dir -> date. How???
      }
      case _ => None
    }
  }
}

The method listFiles(path: String) returns a Seq[String] of absolute path of all files in the path passed as argument to the function

2
  • What does listFiles return? Commented Nov 6, 2016 at 15:25
  • @YuvalItzchakov Seq[String] which is a list of absolute paths for all files in the directory Commented Nov 6, 2016 at 15:26

3 Answers 3

0

Try to write more idiomatic Scala. Something like this:

val directoryToFile = (for {
    path <- awsClient.listFiles(uploadPath)
    if !path.endsWith("/")
    regex(dir, date) <- regex.findFirstIn(path)
} yield dir -> date).sortBy(_._2).toMap
Sign up to request clarification or add additional context in comments.

2 Comments

What sortBy is for? Map in Scala is unordered.
You said you wanted only the last (most recent) date associated with each dir. This is the purpose of the sortBy statement. You can also remove that, if you do not need it.
0

You can filter and then foldLeft:

val l = List("""/opt/file1.txt""", """/opt/file2.txt""")
val finalMap = l
                .filter(!_.endsWith("/"))
                .foldLeft(Map.empty[String, LocalDateTime])((map, s) =>
  s match {
    case regex(dir, date) => map + (dir -> date)
    case _ => map
  }
)

6 Comments

thanks! What about the "collect" method where I was filtering out some elements based on a certain criteria in the original code?
You can apply a filter before using foldLeft. Edited the answer.
thank you! Now, I minor update: there could be a situation that the same directory may have multiple files denoted by date: "dir1/2016-01-01.txt" and "dir1/2013-01-01/txt". In that case, I want the hashmap to only keep the value with the latest file date.. how can I use "max" function to do that?
+ on immutable.Map with the same key will override the previous entry.
See my solutions. I have added your "max" function.
|
-1

You can try something like this:

val regex =  """(\d)-(\d)""".r
val paths = List("1-2", "3-4", "555")

for {

  // Hint to Scala to produce specific type
  _ <- Map("" -> "")

  // Not sure why your !path.endsWith("/") is not part of regex
  path@regex(a, b) <- paths
  if path.startsWith("1")

} yield (a, b)

//> scala.collection.immutable.Map[String,String] = Map(1 -> 2)

Slightly more complicated if you need max:

val regex =  """(\d)-(\d)""".r
val paths = List("1-2", "3-4", "555", "1-3")

for {
  (_, ps) <-
    ( for {
        path@regex(a, b) <- paths
        if path.startsWith("1")
      } yield (a, b)
    ).groupBy(_._1)
} yield ps.maxBy(_._2)

//> scala.collection.immutable.Map[String,String] = Map(1 -> 3)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.