2010-03-18 8 views
6

Esto es algo que encuentro con frecuencia, pero no conozco la manera elegante de hacerlo. Tengo una colección de objetos Foo. Foo tiene una barra de método() que puede devolver un objeto nulo o Bar. Quiero escanear la colección, llamar al método bar() de cada objeto y detenerme en el primero devolviendo una referencia real y devolver esa referencia desde el escaneo.mejor idioma de scala para encontrar y devolver

Obviamente:

foos.find (.! _ Bar = null) .bar

hace el truco, pero pide #bar dos veces.

Respuesta

7

usted puede hacerlo con cualquier Iterable utilizando iterator (que evalúa con pereza - que se llama elements en 2.7). Pruebe esto:

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

¿Hay alguna diferencia entre esto y el uso de una proyección? – IttayD

+0

La memorización de Stream [T] es la diferencia 'val mapped = foos.elements.map (_. Bar); mapped.find (_! = null); mapped.find (_! = null) 'devuelve' Some (bar say 4) 'y' None' donde 'val mapped = foos.projection.map (_. bar); mapped.find (_! = null); mapped.find (_! = null) 'devuelve dos veces' Some (bar say 4) '. –

+0

'foos.view' en Scala 2.8 devuelve lo mismo que' foos.projection', pero evalúa los elementos dos veces (no hace memoria). –

8

Trabajando en la Corriente [T] devuelto por Seq.projection es un buen truco

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

Esto mapear los valores necesarios para ejecutar hallazgo.

En Scala 2.8 es:

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