[英]Scala iterate over list
如何在不使用可变集合的情况下将List(1,2,30,13,4)
转换为List(1,2,3,4)
?
30是一种转义号码; 如果找到,应将其删除,下一个数字应减少10。
无论如何,您可能应该检查您的代码/用例,因为有点类似:
List(1,2,30,13,4).foldLeft((List.empty[Int], false)) {
case ((accumulator, wasFound), next) =>
if(wasFound) (accumulator :+ (next - 10), false)
else if(next == 30) (accumulator, true)
else (accumulator :+ next, false)
}._1
基本上,您可以保留一个布尔值和一个累加器,并使用它来记住是否找到了30,并采取适当的措施以防万一。
请注意,如果您有类似List(1,3,30,40)
的输出,这将对您没有帮助,输出将是List(1,3,30)
,您应该弄清楚这种情况是否可以接受,如果不,我将使用一个递归解决方案,该解决方案允许在元素为30的情况下对元素进行两次迭代:
scala> def loop(list: List[Int], acc: List[Int], wasFound: Boolean, toRemove: Int): List[Int] = list match {
| case h :: t =>
| if(wasFound) loop((h - 10) :: t, acc, false, toRemove)
| else if(h == toRemove) loop(t, acc, true, toRemove)
| else loop(t, acc :+ h, false, toRemove)
| case Nil =>
| acc
| }
loop: (list: List[Int], acc: List[Int], wasFound: Boolean, toRemove: Int)List[Int]
scala> loop(List(1,2,30,13,4), List(), false, 30)
res1: List[Int] = List(1, 2, 3, 4)
scala> loop(List(1,2,30,40, 13,4), List(), false, 30)
res2: List[Int] = List(1, 2, 3, 4)
逻辑非常相似,唯一的不同是您对30之后的那个进行了两次迭代,因此,如果它又是30,则将其删除并减少下一个。
将上一个项目压缩到每个项目,然后使用collect
和部分函数确定是否返回什么:
l.zip(l.head :: l).collect {
case (v, 30) if v != 30 => v - 10 // only previous is 30 - decrease 10
case (v, prev) if v != 30 => v // none of them is 30 - just return value
// skipping (filtering out) case where v == 30
}
例如:
val l = List(1,2,30,13,4,30,15,6)
,这将返回List(1,2,3,4,5,6)
val l = List(1,3,30,40)
,返回List(1,3,30)
val l = List(30,11,2)
,返回List(1,2)
遵循@Victor注释并概括:
def escapeAdjust[A](xs: List[A], p: A => Boolean, f: A => A): List[A] = {
@tailrec
def loop(ys: List[A], p: A => Boolean, f: A => A, acc: List[A]): List[A] = ys match {
case Nil => acc
case h :: Nil => if (p(h)) acc else h :: acc
case h :: next :: rest => if (p(h)) loop(f(next) :: rest, p, f, acc)
else loop(next :: rest, p, f, h :: acc)
}
loop(xs, p, f, List[A]()).reverse
}
用法:
val p = (x: Int) => x == 30
val f = (y: Int) => y - 10
escapeAdjust(List[Int](1,2,30,13,4), p, f)
res12: List[Int] = List(1, 2, 3, 4)
escapeAdjust(List(1,2,30,13,4,30,15,6), p, f)
res13: List[Int] = List(1, 2, 3, 4, 5, 6)
escapeAdjust(List(1,3,30,40), p, f)
res14: List[Int] = List(1, 3)
escapeAdjust(List(30,11,2), p, f)
res15: List[Int] = List(1, 2)
escapeAdjust(List(1,3,30,40, 5), p, f)
res16: List[Int] = List(1, 3, -5)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.