Scala collectFirst函数返回选项[U]

Nim*_*and 7 optimization scala scala-collections

我已经在我正在编写的库中出现过多次这种情况,而且我对目前为止我提出的解决方案并不是特别满意.

假设我有一个昂贵的函数f,它接受一个T类型的项并返回一个类型为Option [U]的值.现在,假设我有一个类型为T的集合,我希望在跨越T的元素执行时检索f返回的第一个非None值,而不是为T的所有元素评估f(如果已找到该值).

我想出的唯一方法是将F包装到Extractor对象中,并将其与scala的collectFirst方法一起使用.

例如:

object FMatch { def unapply(t : T) = f(t) }

collection.collectFirst{ case FMatch(result) => result }
Run Code Online (Sandbox Code Playgroud)

这似乎有点不优雅,我不确定f是否只对每个结果进行一次或两次评估(我还没有测试过这一点).似乎使用一个版本的collectFirst来获取类型为T => Option [U]而不是PartialFunction1 [T]的参数会很有用.

有没有更优雅的方式来做到这一点,我错过了?

Kev*_*ght 15

在集合上使用一个视图,使其变为惰性并将该函数的调用推迟到最后一刻(例如,对于超出第一个匹配的元素,它将不会被调用):

xs.view map {f(_)} collectFirst {case Some(x) => x}
Run Code Online (Sandbox Code Playgroud)

要么

xs.view map {f(_)} find {_.isDefined}
Run Code Online (Sandbox Code Playgroud)

或者以无点的方式,根据Alexey的回答:

xs.view map {f} find {_.isDefined}
Run Code Online (Sandbox Code Playgroud)

这应该有希望给你几种替代方法来更普遍地思考这个问题:)


Ale*_*nov 9

用这个:

collection.toIterator.map(f).find(_.isDefined)
Run Code Online (Sandbox Code Playgroud)

  • 通过简单地对结果调用`flatten`,或使用`flatMap`或for-comprehension,可以很容易地处理`Option [Option [X]]`; 最好的选择取决于你的情况,我可能会用'flatten`这样的东西.关于视图,它们*应该像任何给定集合的迭代器一样轻量级(如果不是更轻).保罗菲利普斯过去曾提出过一些观点问题,但很久以前就已经解决了这些问题,他们将在2.9.1 ...... (3认同)