我有以下列对(key,id):
val pairs = List(('a',1), ('a',2), ('b',1), ('b',2))
当键不同时,我需要生成所有对的组合 所以预期的输出是:
List(
List(),
List(('a', 1)),
List(('a', 2)),
List(('b', 1)),
List(('a', 1), ('b', 1)),
List(('a', 2), ('b', 1)),
List(('b', 2)),
List(('a', 1), ('b', 2)),
List(('a', 2), ('b', 2))
)
注意(List(('a',1),('a',2))
不应该是输出的一部分,因此使用Scala List.combinations
不是一个选项
我目前有以下代码:
def subSeq (xs: List[(Char, Int)]): List[(Char,Int)] = {
xs match {
case Nil => List()
case y::ys => {
val eh = xs.filter (c => c._1 == y._1)
val et = xs.filter (c => c._1 != y._1)
for (z: (Char,Int) <- eh) yield z :: subSeq(et)
}
}
}
但我收到错误List[List[(Char,Int)]] does not match List[(Char,Int)]
答案 0 :(得分:0)
你可能想要做的是:
def subSeq (xs: List[(Char, Int)]): List[List[(Char,Int)]] = {
xs match {
case Nil => List(List())
case y::ys => {
val eh: List[(Char, Int)] = xs.filter (c => c._1 == y._1)
val et = xs.filter (c => c._1 != y._1)
val t = subSeq(et)
t ++ (for {
z: (Char,Int) <- eh
foo <- t
} yield z :: foo)
}
}
}
您的方法必须返回列表列表,因为这是您感兴趣的内容。因此,在构建组合时,您必须迭代递归步骤的结果。
使用API函数的方法是这样做:
val sets = (0 to 2).flatMap{pairs.combinations}.toSet
sets.map{_.toMap}
或者,如果您需要输出作为列表:
sets.map{_.toMap.toList}.toList
显然,这将构建比您最初需要的更多组合,然后过滤掉东西。如果性能是一个问题并且输入不包含任何冗余,那么直接实现可能会更好。
答案 1 :(得分:0)
最终我使用了Scala的combinations
函数并通过此过滤函数过滤掉了非相关匹配
def filterDup(xs: List[(Char,Int)]) : Boolean = {
xs.map(x => x._1).size == xs.map(x => x._1).toSet.size
}
并将其用作以下内容:
((0 to 3).flatMap(pairs.combinations(_)) filter( filterDup(_))).toList