2010-03-18 22 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)