¿Es posible expresar el siguiente código de forma que el mapa y la omisión nula se expresen en una sola llamada?Combinación de nulos de mapa y filtro en Scala
list.map(_.accept(this, arg).asInstanceOf[T]).filter(_ != null)
¿Es posible expresar el siguiente código de forma que el mapa y la omisión nula se expresen en una sola llamada?Combinación de nulos de mapa y filtro en Scala
list.map(_.accept(this, arg).asInstanceOf[T]).filter(_ != null)
list flatMap { i => Option(i.accept(this, arg).asInstanceOf[T]) }
o, alternativamente, si se quiere, (aunque esto será convertido más o menos en su expresión original)
for {
item <- list
itemConverted = item.accept(this, arg).asInstanceOf[T]
itemNonNull = itemConverted if itemConverted != 0
} yield itemNonNull
usando collect
sería posible pero probablemente llamarían accept
dos veces en la mayoría de los argumentos debido a la prueba isDefinedAt
de la función parcial:
list collect {
case i if i.accept(this, arg).asInstanceOf[T] != null => i.accept(this, arg).asInstanceOf[T]
}
Uno necesitaría usar algunas memorias (o extractores inteligentes) para evitar esto.
gracias por la respuesta! –
Si usted está preocupado por el rendimiento, puede agregar .view
list.view.map(_.accept(this, arg).asInstanceOf[T]).filter(_ != null)
view
hace que el recorrido para convertirse en vago, por lo tanto el map
y filter
se llevará a cabo en un solo pase la lista en lugar de dos pasos separados.
Si usted está preocupado por la reutilización de este patrón, se puede definir su propia función auxiliar:
def mapNN[A,B](list: List[A])(f: A => B) = {
list.view.map(f(_)).filter(_ != null)
}
mapNN(list)(_.accept(this, arg).asInstanceOf[T])
Probando ...
> mapNN(List(1,2,3))(x => if (x%2==0) x else null).toList
res7: List[Any] = List(2)
¿Puedes explicarme más sobre esta parte, así que el mapa y el filtro se realizarán en una pasada sobre la lista en lugar de en dos pases separados? ¿Cómo solo puede necesitar un pase para aplicar 2 transformaciones? –
@MinhThai Aquí hay una explicación decente de 'view': https://stackoverflow.com/a/6799739/208257 Básicamente, hace que las transformaciones sean flojas. Retrasa incluso haciendo una sola pasada, hasta que llamas a 'toList', momento en el que hace una sola pasada, aplicando cada transformación de forma gradual a medida que avanza. –
supongo que '_.accept (esto, arg) 'puede devolver' null'. En este caso, un poco más idiomático (aunque todavía con dos llamadas): 'list.map (i => Opción (i.accept (this, arg) .asInstanceOf [T])). Aplastar' –
Por favor, alguien me corrija si ' estoy equivocado, pero ¿no es 'recoger' la combinación de' map' y 'filter'? ¿O era al revés? ¿O simplemente estoy equivocado? ;) – agilesteel
@agilesteel, sí, collect podría funcionar. ¿Podría contribuir con un fragmento de código? –