2010-03-18 17 views
6

这是我经常遇到的事情,但我不知道这种优雅的方式。我有一个Foo对象的集合。 Foo有一个方法bar(),可以返回null或Bar对象。我想扫描集合,调用每个对象的bar()方法,并停止第一个返回实际引用并从扫描返回该引用。查找并返回最佳斯卡拉成语

很明显:

foos.find(!_吧= NULL)的.bar

的伎俩,但呼吁#bar两次。

回答

7

可以使用iterator与任何Iterable做到这一点(这懒洋洋地评估 - 这就是所谓的elements 2.7)。试试这个:

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) 
+0

这是否有区别和使用投影? – IttayD 2010-03-18 16:04:34

+0

Stream [T]的记忆是不同的'val mapped = foos.elements.map(_。bar); mapped.find(_!= null); mapped.find(_!= null)'returns'某些(bar说4)和'None'其中'val mapped = foos.projection.map(_。bar); mapped.find(_!= null); mapped.find(_!= null)'返回两次'Some(bar say 4)'。 – 2010-03-18 16:22:03

+0

Scala 2.8中的'foos.view'返回与'foos.projection'相同的值,但两次评估元素(不记忆)。 – 2010-03-18 16:25:56

8

在流[T]由Seq.projection返回工作是一个很好的把戏

foos.projection map (_.bar) find (_.size > 0) 

这将映射到执行查找所需的值。

在Scala中2.8是:

foos.view map (_.bar) find (_.size > 0)