我想在一个包含Scala数字的列表中减去两个连续的元素。
例如:我有以下列表:
val sortedList = List(4,5,6)我想要一个像diffList =(1, 1)这样的输出列表,其中5-4 = 1和6-5 = 1。
我尝试了以下代码:
var sortedList = List[Int]()
var diffList = List[Int]()
for (i <- 0 to (sortedList.length - 1) ;j <- i + 1 to sortedList.length - 1)
{
val diff = (sortedList(j) - sortedList(i))
diffList = diffList :+ diff
}对于diffList =(1, 2, 1),我有下面的结果,但是我想要diffList = (1,1)。
这是因为for循环。它不会同时迭代这两个变量(i和j)。
发布于 2021-01-30 19:40:47
为了解决这个问题,您不需要修改或命令式编程,函数式编程给您带来了帮助。
def consecutiveDifferences(data: List[Int]): List[Int] =
if (data.isEmpty) List.empty
else data.lazyZip(data.tail).map {
case (x, y) => y - x
}正如我常说的,Scaladoc是你的朋友。
(此外,作为一种建议,学习函数式编程的最佳方法是禁止自己的易变性)
发布于 2021-01-30 20:42:56
您可以使用sliding方法,根据文档:
/**通过在固定大小块上传递“滑动窗口”*对元素进行分组(而不是像在
grouped中那样对它们进行分区)*一个空集合返回一个空迭代器,包含比窗口大小更少的元素的非空*集合返回*一个迭代器,它将生成原始集合作为其唯一的*元素。*@请参阅[scala.collection.Iterator],方法sliding** @param每个组*@返回一个生成大小为size的${coll}的迭代器,但具有小于size元素的*非空集合除外,它*返回生成源集合本身*作为其唯一元素的迭代器。@示例List().sliding(2) = empty iterator*@示例List(1).sliding(2) = Iterator(List(1))*@List(1, 2).sliding(2) = Iterator(List(1, 2))*@List(1, 2).sliding(2) = Iterator(List(1, 2))*示例List(1, 2, 3).sliding(2) = Iterator(List(1, 2), List(2, 3))*/
然后,解决您的查询是非常直接的:
diffList = sortedList.sliding(2).collect {
case Seq(a, b) =>
b - a
}.toList这导致了List(1,1)
代码在斯卡斯蒂上运行。
发布于 2021-01-30 19:57:08
for(i <- 0 until (sortedList.size - 1)) yield sortedList(i + 1) - sortedList(i)生成Vector(1,1),可以用toList转换为list
这也可以通过以下功能来实现:
val sortedList = List(4,5,7)
@tailrec
def findDiffs(xs: List[Int])(seed: List[Int]): List[Int] = {
if(xs.isEmpty || xs.size == 1) seed.reverse
else {
val currDiff = xs(1) - xs(0)
findDiffs(xs.tail)(currDiff :: seed)
}
}
val res = findDiffs(sortedList)(Nil)
println(res)或者只是简单地用拉链:
sortedList.drop(1) zip sortedList map { case (x,y) => x - y } https://stackoverflow.com/questions/65972252
复制相似问题