如果我正确理解了这个问题,那么结果列表的每个条目都应该是一个列表,其中包含与原始列表中的元素一样多的元组。也就是说,我认为您基本上是在问如何编写“可变长度的理解”,其中所需的生成器数量取决于参数。
为此,您不妨考虑一下 for-comprehension desugars 是什么,然后制作它的递归版本,如下所示:
$ cat x.scala
object X extends App {
// Some lists.
val t1 = List(1,2)
val t2 = List(4,5,6)
val t3 = List(7,8)
// What I think you expect the output to look like for three lists.
val result1 = for ( a1<-t1; a2<-t2; a3<-t3 ) yield List( (1,a1), (2,a2), (3,a3) )
println(result1)
// Here's what that desugars to.
val result2 = t1 flatMap ( a1 => t2 flatMap( a2 => t3 map( a3 => List( (1,a1), (2,a2), (3,a3) ) ) ) )
println(result2)
println( result2 == result1 )
// Here is how to do the same thing when you don't know how many lists there are.
// We're going to assume there is at least one; you could of course add a check.
def combine( lists:List[List[Int]], i:Int=1, soFar:List[(Int,Int)]=Nil ):List[List[(Int,Int)]] =
lists match {
case head::Nil => head.map ( x => ( (i,x)::soFar ).reverse )
case head::rest => head.flatMap( x => combine( rest, i+1, (i,x)::soFar ) )
}
// Now let's see if that gives us the same answer.
val result3 = combine( List(t1,t2,t3) )
println(result3)
println( result3 == result1 )
}
$ scalac x.scala
$ scala X
List(List((1,1), (2,4), (3,7)), List((1,1), (2,4), (3,8)), List((1,1), (2,5), (3,7)), List((1,1), (2,5), (3,8)), List((1,1), (2,6), (3,7)), List((1,1), (2,6), (3,8)), List((1,2), (2,4), (3,7)), List((1,2), (2,4), (3,8)), List((1,2), (2,5), (3,7)), List((1,2), (2,5), (3,8)), List((1,2), (2,6), (3,7)), List((1,2), (2,6), (3,8)))
List(List((1,1), (2,4), (3,7)), List((1,1), (2,4), (3,8)), List((1,1), (2,5), (3,7)), List((1,1), (2,5), (3,8)), List((1,1), (2,6), (3,7)), List((1,1), (2,6), (3,8)), List((1,2), (2,4), (3,7)), List((1,2), (2,4), (3,8)), List((1,2), (2,5), (3,7)), List((1,2), (2,5), (3,8)), List((1,2), (2,6), (3,7)), List((1,2), (2,6), (3,8)))
true
List(List((1,1), (2,4), (3,7)), List((1,1), (2,4), (3,8)), List((1,1), (2,5), (3,7)), List((1,1), (2,5), (3,8)), List((1,1), (2,6), (3,7)), List((1,1), (2,6), (3,8)), List((1,2), (2,4), (3,7)), List((1,2), (2,4), (3,8)), List((1,2), (2,5), (3,7)), List((1,2), (2,5), (3,8)), List((1,2), (2,6), (3,7)), List((1,2), (2,6), (3,8)))
true