我是Scala的新手,非常感谢任何方向或帮助解决以下问题。
输入
我有Map[String, Array[Double]]
,如下所示:
Map(foo -> Array(12, 25, 100), bar -> Array(0.1, 0.001))
Map可以包含1到10个键(取决于我的应用程序中的一些参数)。
处理
我想在所有键的数组之间应用笛卡尔积,并生成一个包含所有数组所有值的所有可能组合的结构。
在上面的示例中,笛卡尔积将创建3x2=6
个不同的组合:(12, 0.1), (12, 0.001), (25, 0.1), (25, 0.01), (100,0.1) and (100, 0.01)
。
为了另一个例子,在某些情况下我可能有三个键:第一个键具有4个值的数组,第二个键具有5个值的数组,第三个键具有3个值的数组,在这种情况下该产品必须生成4x5x3=60
种不同的组合。
所需的输出
类似的东西:
Map(config1 -> (foo -> 12, bar -> 0.1), config2 -> (foo -> 12, bar -> 0.001), config3 -> (foo -> 25, bar -> 0.1), config4 -> (foo -> 25, bar -> 0.001), config5 -> (foo -> 100, bar -> 0.1), config6 -> (foo -> 100, bar -> 0.001))
答案 0 :(得分:1)
您可以使用for comprehension来创建两个列表的笛卡尔积,数组......
val start = Map(
'foo -> Array(12, 25, 100),
'bar -> Array(0.1, 0.001),
'baz -> Array(2))
// transform arrays into lists with values paired with map key
val pairedWithKey = start.map { case (k,v) => v.map(i => k -> i).toList }
val accumulator = pairedWithKey.head.map(x => Vector(x))
val cartesianProd = pairedWithKey.tail.foldLeft(accumulator)( (acc, elem) =>
for { x <- acc; y <- elem } yield x :+ y
)
cartesianProd foreach println
// Vector(('foo,12), ('bar,0.1), ('baz,2))
// Vector(('foo,12), ('bar,0.001), ('baz,2))
// Vector(('foo,25), ('bar,0.1), ('baz,2))
// Vector(('foo,25), ('bar,0.001), ('baz,2))
// Vector(('foo,100), ('bar,0.1), ('baz,2))
// Vector(('foo,100), ('bar,0.001), ('baz,2))
在使用head
和tail
之前,您可能需要添加一些检查。
答案 1 :(得分:1)
由于数组的数量是动态的,因此无法将结果作为结果。
但是,您可以将递归用于您的目的:
def process(a: Map[String, Seq[Double]]) = {
def product(a: List[(String, Seq[Double])]): Seq[List[(String, Double)]] =
a match {
case (name, values) :: tail =>
for {
result <- product(tail)
value <- values
} yield (name, value) :: result
case Nil => Seq(List())
}
product(a.toList)
}
val a = Map("foo" -> List(12.0, 25.0, 100.0), "bar" -> List(0.1, 0.001))
println(process(a))
结果如下:
List(List((foo,12.0), (bar,0.1)), List((foo,25.0), (bar,0.1)), List((foo,100.0), (bar,0.1)), List((foo,12.0), (bar,0.001)), List((foo,25.0), (bar,0.001)), List((foo,100.0), (bar,0.001)))