我跟随Seq作为输入:
Seq(Seq(1,2),Seq(2,3),Seq(3,4),Seq(7,8),Seq(8,9))
我想从下面创建另一个Seq:
Seq(Seq(1,4),Seq(7,9))
我认为使用滑动操作(取2)并合并设置以删除重复但我不知道如何使用Seq实现它,因为它是不可变的。有人能帮助我吗?
答案 0 :(得分:3)
我不确定我是否理解正确,但请尝试以下代码:
val input = Seq(Seq(1, 2), Seq(2, 3), Seq(3, 4), Seq(7, 8), Seq(8, 9))
input.flatten.groupBy(x => x).mapValues(_.size).filter{
case (key, value) => value == 1
}.keySet.toList.sorted.grouped(2).toList
这样的输出是:
input: Seq[Seq[Int]] = List(List(1, 2), List(2, 3), List(3, 4), List(7, 8), List(8, 9))
res0: List[List[Int]] = List(List(1, 4), List(7, 9))
答案 1 :(得分:1)
如果我理解正确,您希望删除所有连续的重复值,这样如果您有Seq(..., (a, b), (b, c), ...)
,则返回Seq(..., (a, c), ...)
如果你的内部Seq
中总是有两个元素,你应该使用成对而不是Seq
(因为在编译时尽可能多的信息应该在类型中给出),所以我会成对做,希望你能够在需要的时候进行调整。
def merge(l: Seq[(Int, Int)], acc: Seq[(Int, Int)] = Seq()): Seq[(Int, Int)] = l match {
//if there's less than one element left, nothing can be merged
case Seq() | Seq(_) => acc ++ l
//if the first two elements are mergeable, merge them and call recursively (to allow merging the new pair with the next element)
case (a, b) +: (c, d) +: tail if b == c => merge((a, d) +: tail, acc)
//if the first two elements are not mergeable, put the first one in the accumulator, and carry on
case p +: tail => merge(tail, acc :+ p)
}
您可以用foldLeft
替换这个尾递归函数,但我发现它更具可读性。
答案 2 :(得分:0)
Cyrille Corpet答案的foldLeft
版本,坚持使用(Int, Int)
对:
val data = Seq(Seq(1, 2), Seq(2, 3), Seq(3, 4), Seq(7, 8), Seq(8, 9))
.map(s => (s.head, s.last)) // Seq((1, 2), (2, 3), ...)
val merged = data.foldLeft(Seq[(Int, Int)]())((acc, e) =>
acc match {
case (a, b) +: tail if (b == e._1) => (a, e._2) +: tail
case head +: tail => e +: acc
case Nil => Seq(e)
}).reverse // Seq((1, 4), (7, 9))
val mergedToSeq = merged.map(s => Seq(s._1, s._2)) // Seq(Seq(1, 4), Seq(7, 9))
答案 3 :(得分:0)
更通用的Seq
解决方案可能是:
val data = Seq(Seq(1,2),Seq(2,3),Seq(3,4),Seq(7,8),Seq(8,9))
val merged = data.foldLeft(Seq.empty[Seq[Int]]) {
case (acc :+ (last :+ tail), head :: e)
if tail == head => acc :+ (last ++ e)
case (acc, e) => acc :+ e
} //List(List(1, 4), List(7, 9))