2

我想编写一个函数,它接受一个序列列表,其中每个序列都将用于理解表达式。

例如。

for (x <- (1 to 10); y <- (1 to 10)) yield List(x,y)

在上面的表达式中,我必须事先知道我想要 x 和 y 的组合。如果我想要 x、y、z ...等的组合(未知数量的组合)怎么办?如果我想要 10 个组合,我想将 10 个片段“x <- (1 to 10)”粘贴到表达式中。我想我可以用 Clojure 中的宏(一种粘贴代码的方法)来做到这一点。我怎样才能在 Scala 中做到这一点?

我想写的函数有这样的签名:

combine(list: List[List[Int]])

函数的主体将使用列表中的每个项目粘贴到 for comprehension 中。

希望你明白我的意图。

4

2 回答 2

2

如果要计算列表列表的笛卡尔积,可以通过递归地将 map 和 flatMap 调用链接在一起来实现。无论如何,这就是表达式的作用。

  def prod(l:List[List[Int]]):List[List[Int]] = l match {
    case Nil => List(Nil)
    case l::ls => l.flatMap(i => prod(ls).map(t =>i::t))
  }
于 2012-09-23T16:20:17.557 回答
1

你知道如何将两个东西组合成一个东西,并且你想组合一个任意数字,这意味着你需要一个fold. 唯一的修改是您希望从单例列表开始,而不是项目列表:

val xss = List(List(1,2,3),List(4,5),List(6,7))
val singletons = xss.head.map(x => List(x))   // List(List(1), ...)
val seqs = (singletons /: xss.tail){ (yss, xs) => for (ys <- yss; x <- xs) yield x :: ys }
seqs.map(_.reverse)

在最后阶段打印出来

List(List(1, 4, 6), List(1, 4, 7), List(1, 5, 6),
     List(1, 5, 7), List(2, 4, 6), List(2, 4, 7),
     List(2, 5, 6), List(2, 5, 7), List(3, 4, 6),
     List(3, 4, 7), List(3, 5, 6), List(3, 5, 7))
于 2012-09-23T16:27:53.503 回答