This is something I encounter fre开发者_StackOverflow社区quently, but I don't know the elegant way of doing. I have a collection of Foo objects. Foo has a method bar() that may return null or a Bar object. I want to scan the collection, calling each object's bar() method and stop on the first one returning an actual reference and return that reference from the scan.
Obviously:
foos.find(_.bar != null).bar
does the trick, but calls #bar twice.
Working on the Stream[T] returned by Seq.projection is a nice trick
foos.projection map (_.bar) find (_.size > 0)
This will map the values needed to execute find.
In Scala 2.8 it's:
foos.view map (_.bar) find (_.size > 0)
You can do it with any Iterable
by using iterator
(which evaluates lazily--it's called elements
in 2.7). Try this out:
case class Foo(i: Int) {
def bar = {
println("Calling bar from Foo("+i+")")
(if ((i%4)==0) "bar says "+i else null)
}
}
val foos = List(Foo(1),Foo(2),Foo(3),Foo(4),Foo(5),Foo(6))
foos.iterator.map(_.bar).find(_!=null)
精彩评论