我有这个函数基本上结合了列表的列表,但你可以忽略它,因为这不是问题:
def combinationList[T](ls:List[List[List[T]]]) : List[List[List[T]]] = ls match {
case head :: Nil => for(x <- head) yield List(x)
case head :: tail :: Nil =>
for {
hl <- head
tl <- tail
if tl.forall(te => !hl.contains(te))
} yield List(hl, tl)
}
当我有一个带有两个子列表的列表但是当我有两个以上时,它无法匹配。我显然需要递归地使用这个函数来做一个更一般的情况,并且我试图在函数的末尾添加以下案例:
case _ => combinationList(combinationList(ls.tail):::List(ls.head))
这里的逻辑是,假设我们有一个包含3个子列表的List,如下所示:
List ( List(1), List(2), List(3) )
当我第一次调用fucntion时,它只会在我提到的最后一种情况下匹配,因此,我将调用带有列表尾部的函数(List(2),List(3)),以及在该调用中,它将匹配第二种情况(head :: tail :: Nil),然后,当它返回时,它应该是单个List并且当被添加到列表的原始头部时(List(1) :: List(2 + 3))它应该匹配第二个条件。这里的问题是返回不是单个列表(List(2 + 3))而是列表的另一个组合(List(2),List(3))所以它显然会永远递归。我试图像这样修改案例:
combinationList(List(combinationList(ls.tail)):::List(ls.head))
但是它给了我一个错误(&#34; List [List [List [Any]]类型的表达式不符合List [List [List [T]]]&#34;
有什么想法吗?感谢。
[编辑:]此功能的目的是以这种方式组合列表:
simplified input: List( List(1,2), List(3), List(4))
simplified output: List( List(1,3,4), List(2,3,4))
real input: List(
List(List(1), List(3), List(4)),
List(List(2), List(3), List(4))
)
real expected output: List(
List(List(1), List(2)),
List(List(1), List(3)),
List(List(1), List(4)),
List(List(3), List(2)),
List(List(3), List(4)),
List(List(4), List(2)),
List(List(4), List(3))
)
使用实际输入,该函数能够返回预期的输出,它只在添加另一个子列表时失败,如下所示:
input: List(
List(List(1), List(2)),
List(List(3), List(4)),
List(List(5))
)
此处的预期输出为:
expected output: List(
List(List(1), List(3), List(5)),
List(List(1), List(4), List(5)),
List(List(2), List(3), List(5)),
List(List(2), List(4), List(5))
)
所以,组合的顺序并不重要,我可以负责:::尾巴或尾巴:::头,它是一样的。
答案 0 :(得分:1)
我仍然不知道为什么你想要三层嵌套。但是,以下通用方法适用于所有示例,包括整数和列表:
def combinationList[T](ls: List[List[T]]): List[List[T]] = {
def recHelper(remainingLs: List[List[T]], blacklist: Set[T]): List[List[T]] = {
remainingLs match {
case Nil => List(Nil)
case h :: t => for {
x <- h.filterNot(blacklist.contains)
xs <- recHelper(t, blacklist + x)
} yield x :: xs
}
}
recHelper(ls, Set.empty)
}
此实现不会过滤掉与! .contains
的任何组合,而是会维护一组列入黑名单的元素,并且不会首先生成无效组合。
一些例子:
def showExample[T](input: List[List[T]]): Unit = {
println("=" * 60)
println(input)
println("-" * 60)
for (c <- combinationList(input)) {
println(" " + c)
}
}
showExample(List(List(1, 2), List(3), List(4)))
showExample(List(List(1, 2, 3), List(2, 3, 4), List(2, 3, 5)))
showExample(List(
List(List(1), List(3), List(4)),
List(List(2), List(3), List(4))
))
showExample(List(
List(List(1), List(2)),
List(List(3), List(4)),
List(List(5))
))
输出:
============================================================
List(List(1, 2), List(3), List(4))
------------------------------------------------------------
List(1, 3, 4)
List(2, 3, 4)
============================================================
List(List(1, 2, 3), List(2, 3, 4), List(2, 3, 5))
------------------------------------------------------------
List(1, 2, 3)
List(1, 2, 5)
List(1, 3, 2)
List(1, 3, 5)
List(1, 4, 2)
List(1, 4, 3)
List(1, 4, 5)
List(2, 3, 5)
List(2, 4, 3)
List(2, 4, 5)
List(3, 2, 5)
List(3, 4, 2)
List(3, 4, 5)
============================================================
List(List(List(1), List(3), List(4)), List(List(2), List(3), List(4)))
------------------------------------------------------------
List(List(1), List(2))
List(List(1), List(3))
List(List(1), List(4))
List(List(3), List(2))
List(List(3), List(4))
List(List(4), List(2))
List(List(4), List(3))
============================================================
List(List(List(1), List(2)), List(List(3), List(4)), List(List(5)))
------------------------------------------------------------
List(List(1), List(3), List(5))
List(List(1), List(4), List(5))
List(List(2), List(3), List(5))
List(List(2), List(4), List(5))
一些提示:
x :: y :: Nil
仅匹配长度为2的列表。