【问题标题】:Expand Map[String,List[String]] into Cartesian Product in Scala在 Scala 中将 Map[String,List[String]] 展开为笛卡尔积
【发布时间】:2021-06-25 12:39:30
【问题描述】:

我正在寻找基于地图类型的Expand a Set[Set[String]] into Cartesian Product in Scala 版本:

我想从:

val values = Map(
      "id" -> List("Paul","Joe"),
      "number" -> List("1","2","3"),
      "Type" -> List("A","B","C")
    )

并计算:

val final = Set(
Map("id" -> "Paul", "number" -> "1", "Type" -> "A" ),
Map("id" -> "Paul", "number" -> "1", "Type" -> "B" ),
Map("id" -> "Paul", "number" -> "1", "Type" -> "C" ),
Map("id" -> "Paul", "number" -> "1", "Type" -> "A" ),
Map("id" -> "Paul", "number" -> "1", "Type" -> "B" ),
Map("id" -> "Paul", "number" -> "1", "Type" -> "C" ),
Map("id" -> "Paul", "number" -> "2", "Type" -> "A" ),
Map("id" -> "Paul", "number" -> "2", "Type" -> "B" ),
Map("id" -> "Paul", "number" -> "2", "Type" -> "C" ),
....
Map("id" -> "Joe", "number" -> "3", "Type" -> "B" ),
Map("id" -> "Joe", "number" -> "3", "Type" -> "C" )
)

我尝试转换以下代码

def combine[A](xs: Traversable[Traversable[A]]): Seq[Seq[A]] =
     xs.foldLeft(Seq(Seq.empty[A])){
     (x, y) => for (a <- x.view; b <- y) yield a :+ b }

但我有一些问题要了解如何构建所有地图以添加到大 Set() 中

【问题讨论】:

    标签: list scala combinations cartesian-product cartesian


    【解决方案1】:

    您可以这样做:
    (但请注意,对于较大的地图,这会消耗大量内存,可能值得考虑生成一个 LazyList

    def cartesianProductMap[A, B](data: Map[A, List[B]]): List[Map[A, B]] =
      data.foldLeft(Map.empty[A, B] :: Nil) {
        case (acc, (key, values)) =>
          values.flatMap { b =>
            acc.map(_ + (key -> b))
          }
      }
    

    代码在Scastie中运行


    顺便说一句,如果你使用 cats,你可以这样做:values.to(SortedMap).sequence

    【讨论】:

      猜你喜欢
      • 2011-02-22
      • 1970-01-01
      • 2019-09-10
      • 2016-07-21
      • 2020-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多