create a map from list in Scala

2019-09-14 21:18发布

问题:

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

回答1:

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


回答2:

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
  }
)


回答3:

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)