【问题标题】:create a map from list in Scala从 Scala 中的列表创建地图
【发布时间】:2016-11-06 15:24:15
【问题描述】:

我需要在 scala 中创建目录到文件的 HashMap,同时列出目录中的所有文件。我怎样才能在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
    }
  }
}

listFiles(path: String) 方法返回作为参数传递给函数的path 中所有文件的绝对路径Seq[String]

【问题讨论】:

  • listFiles 返回什么?
  • @YuvalItzchakov Seq[String] 这是目录中所有文件的绝对路径列表

标签: java scala scala-collections


【解决方案1】:

尝试编写更惯用的 Scala。像这样的:

val directoryToFile = (for {
    path <- awsClient.listFiles(uploadPath)
    if !path.endsWith("/")
    regex(dir, date) <- regex.findFirstIn(path)
} yield dir -> date).sortBy(_._2).toMap

【讨论】:

  • sortBy 是干什么用的? Scala 中的Map 是无序的。
  • 您说您只想要与每个目录关联的最后(最近)日期。这就是 sortBy 语句的目的。如果不需要,也可以删除它。
【解决方案2】:

你可以filter然后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
  }
)

【讨论】:

  • 谢谢!我根据原始代码中的特定条件过滤掉一些元素的“收集”方法呢?
  • 您可以在使用foldLeft 之前申请filter。编辑了答案。
  • 谢谢!现在,我进行了小更新:可能存在同一个目录可能有多个文件以日期表示的情况:“dir1/2016-01-01.txt”和“dir1/2013-01-01/txt”。在这种情况下,我希望哈希图只保留最新文件日期的值。我如何使用“max”函数来做到这一点?
  • + on immutable.Map 使用相同的键将覆盖先前的条目。
  • 查看我的解决方案。我已经添加了你的“最大”功能。
【解决方案3】:

你可以试试这样的:

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)

如果你需要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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-09
    • 2015-09-27
    • 2020-11-05
    • 1970-01-01
    • 2020-08-04
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多