如果您在Scala中有一个Integer列表,并且想要对其进行迭代,并将每两个具有相同值的邻居相加并将其作为列表返回,那么该怎么做呢?
例如:
List(4, 4, 2, 6) => List(8, 2, 6)
我对Scala完全陌生,但是我可以想象模式匹配或映射可能会有用。
def sumSameNeighbours: List[Int] => List[Int] = {
ls match {
case l1::l2:ls => l1 == l2
}
}
这是我能想到的。
编辑:我将如何更改代码以便从右到左而不是从左到右进行迭代?
所以会是:
List(2, 2, 2, 6, 4) => List(2, 4, 6, 4)
代替
List(2, 2, 2, 6, 4) => List(4, 2, 6, 4)
答案 0 :(得分:4)
这非常接近您的建议,并且似乎可以正常工作:
import scala.annotation.tailrec
def sumSameNeighbors( ls : List[Int] ) : List[Int] = {
@tailrec
def walk( unsummed : List[Int], reverseAccum : List[Int] ) : List[Int] = {
unsummed match {
case a :: b :: rest if a == b => walk( rest, a + b :: reverseAccum )
case a :: rest => walk( rest, a :: reverseAccum )
case Nil => reverseAccum.reverse
}
}
walk( ls, Nil )
}
答案 1 :(得分:3)
注意: 根据最终OP的规范说明,此答案并不完全符合问题要求。
这是使用List.grouped(2)
的解决方案:
list.grouped(2).toList
.flatMap {
case List(a, b) if a == b => List(a + b)
case l => l
}
该想法是将连续元素按对分组。如果这对元素具有相同的元素,则将它们的总和返回为flatMaped,否则两个元素都保持不变。
List(4, 4, 2, 6) => List(8, 2, 6)
List(2, 4, 4, 2, 6) => List(2, 4, 4, 2, 6)
List(2) => List(2)
List(9, 4, 4, 4, 2, 6) => List(9, 4, 8, 2, 6)
答案 2 :(得分:0)
使用foldRight
的另一种方法,我发现在创建一个新集合时遍历集合是一种很好的默认方法:
list.foldRight(List.empty[Int]) {
case (x, y :: tail) if x == y => (x + y) :: tail
case (x, list) => x :: list
}
根据要求,List(2, 2, 2, 6, 4)
的输出为List(2, 4, 6, 4)
。
我在您的示例中不清楚的主要是,如果求和产生了新的邻居,输出应该是什么:List(8, 4, 2, 2)
应该变成List(8, 4, 4)
还是List(16)
?这将产生第二个。