【问题标题】:How do I transform a List[String] to a List[Map[String,String]] given that the list of string represents the keys to the map in Scala?鉴于字符串列表表示 Scala 中映射的键,如何将 List[String] 转换为 List[Map[String,String]]?
【发布时间】:2023-03-21 09:20:02
【问题描述】:

我有references的列表:

val references: List[String]= List("S","R")

我也有variables,即:

val variables: Map[String,List[String]]=("S"->("a","b"),"R"->("west","east"))

references 是变量映射的键列表。

我想构造一个函数:

def expandReplacements(references:List[String],variables:Map[String,List[String]]):List[Map(String,String)]

这个函数基本上应该创建返回以下组合

List(Map("S"->"a"),("R"->"west"),Map("S"->"a"),("R"->"east"),Map("S"->"b"),("R"->"west"),Map("S"->"b"),("R"->"east"))

我试过这样做:

val variables: Map[String,List[String]] = Map("S" -> List("a", "b"), "R" -> List("east", "central"))
val references: List[String] = List("S","R")

def expandReplacements(references: List[String]): List[Map[String, String]] =
  references match {
    case ref :: refs =>
      val variableValues =
        variables(ref)
      val x = variableValues.flatMap { variableValue =>
        val remaining = expandReplacements(refs)
        remaining.map(rem => rem + (ref -> variableValue))
      }
      x

    case Nil => List.empty
  }

【问题讨论】:

    标签: list scala recursion maps


    【解决方案1】:

    如果你有超过 2 个参考,你可以这样做:

    def expandReplacements(references: List[String], variables :Map[String,List[String]]): List[Map[String, String]] = {
      references match {
        case Nil => List(Map.empty[String, String])
        case x :: xs =>
          variables.get(x).fold {
            expandReplacements(xs, variables)
          } { variableList =>
            for {
              variable <- variableList.map(x -> _)
              otherReplacements <- expandReplacements(xs, variables)
            } yield otherReplacements + variable
          }
      }
    }
    

    代码在Scastie 运行。

    【讨论】:

      【解决方案2】:

      所以我想通了

      def expandSubstitutions(references: List[String]): List[Map[String, String]] =
              references match {
                case r :: Nil => variables(r).map(v => Map(r -> v))
                case r :: rs  => variables(r).flatMap(v => expandSubstitutions(rs).map(expanded => expanded + (r -> v)))
                case Nil      => Nil
              }
      

      返回:

      List(Map(R -> west, S -> a), Map(R -> east, S -> a), Map(R -> west, S -> b), Map(R -> east, S -> b))
      

      【讨论】:

      • 只有在variables 中存在所有references 的情况下,这才是一个很好的解决方案。请看scastie.scala-lang.org/DxXGA5TwR8WwrL6OgFLyuQ
      • 是的,在我的用例中,这就是我事先检查参考的意图! , 感谢您的帮助 非常感谢
      • 我不会修改我的解决方案,因为它更安全,以供将来参考,但在您的情况下,您可以简化我的解决方案:scastie.scala-lang.org/crQCb7XpRxOwbUhPR8Iycw,这与您的几乎相同,只需您编写flatMapmap 明确:) 编码快乐!
      【解决方案3】:

      您的参考表示不是最理想的,但如果您想使用它...

      val variables: Map[String,List[String]] = [S -> List("a", "b"), R -> List("east", "central")]
      val references: List[String] = List("S","R")
      
      def expandReplacements(references: List[String]): List[Map[String, String]] =
        references match {
          case List(aKey, bKey) =>
            val as = variables.get(aKey).toList.flatten
            val bs = variables.get(bKey).toList.flatten
      
            as.zip(bs).map { case (a, b) =>
              Map(aKey -> a, bKey -> b)
            }
          case _ => Nil
        }
      

      【讨论】:

      • 作者不要求这适用于任何其他情况,所以我不支持任何其他情况。
      • 你是对的,但很多时候 OP 都在简化问题,以便更好地针对他们的用例扩展它。我没有说它不起作用。我只是说它专门用于这个用例。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 2016-07-21
      • 2018-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多