以下内容的正确语法是什么?
var foo = 0
someIterator.foreach{ x => x.property match {
case "a" => foo += 1
case "b" => yield "current foo" + foo
}}
即,我正在尝试迭代someIterator。当它匹配一件事时,它应该通过闭包更新局部变量;当它遇到另一个时,它应该产生一些当前状态的推导到结果迭代器,保留连续迭代的状态。
答案 0 :(得分:5)
您可以使用Option[String]
,unlift
和collect
。
unlift
接受一个返回选项的函数,并将其转换为部分函数。collect
与map
类似,只是它只考虑定义部分函数的元素。以下示例演示了该方法:
import Function.unlift
var foo = 0
someIterator.map(_.property).collect(unlift {
case "a" => foo += 1; None
case "b" => Some("current foo" + foo)
})
答案 1 :(得分:1)
如果你只想得到foo
的最终值,那么你可以使用尾递归,你也不必使用可变变量。
@annotation.tailrec
def f(l: List[Char], foo: Int = 0):Int= {
if (l == Nil) foo
else {
l.head match {
case 'a' => f(l.tail, foo + 1)
case 'b' => f(l.tail, foo)
}
}
}
val l1 = List('a','b')
f(l1)
l1: List[Char] = List(a, b)
res0: Int = 1
答案 2 :(得分:1)
您可以使用scanLeft
的累加器代替变量:
someIterator.scanLeft((0, None: Option[String])){
case ((foo, _), "a") => (foo + 1, None)
case ((foo, _), "b") => (foo, Some(s"current foo $foo"))
}.map(_._2).flatten
示例:
val someIterator = List("a","a","a","a","b", "a", "a", "b").toIterator
scala> someIterator.scanLeft(...){...}.map(_._2).flatten
res16: Iterator[String] = non-empty iterator
scala> res16.toList
res17: List[String] = List(current foo 4, current foo 6)
因此你仍然有一个迭代器