Reputation: 29143
This is something I encounter frequently, 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.
Upvotes: 6
Views: 898
Reputation: 33092
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)
Upvotes: 8
Reputation: 167901
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)
Upvotes: 7