2012-06-20 18 views
36

Vorrei filtrare il mio set di dati su due condizioni contemporaneamente.Filtro Scala su due condizioni

È possibile?

voglio qualcosa di simile:

mystuff = mystuff.filter(_.isX && _.name == "xyz") 

risposta

58

Uso della sintassi lambda un po 'meno conciso:

mystuff = mystuff.filter(x => (x.isX && x.name == "xyz")) 

Potete trovare maggiori dettagli su Scala funzione anonima sintassi here.

+1

questo elimina il sovraccarico delle prestazioni? Intendo dire che alla fine la query è espressa correttamente? – zinking

4

Mentre ci potrebbe essere qualche impatto sulle prestazioni a seconda di ciò che "MioAsk" è, si può sempre filtrare due volte

mystuff = mystuff.filter(_.isX).filter(_.name == "xyz") 
+0

Ciò provoca il doppio loop dell'intera lista. – squixy

+5

@squixy solo una FYI, non è così. 'filter' crea una nuova proiezione (o vista) della collezione in modo tale che quando viene richiesto un elemento durante l'iterazione (cioè' map', 'fold', ecc ...) le funzioni' filter' vengono applicate a vedere se l'elemento viene restituito – ThaDon

4

Se è necessario filtrare frequentemente con diversi predicato, è possibile definire un modo di combinare loro:

case class And[A](p1: A=>Boolean, p2: A=>Boolean) extends (A=>Boolean) { 
    def apply(a: A) = p1(a) && p2(a) 
} 

Ecco come usarlo per mantenere solo i numeri dispari maggiori di 10:

scala> (0 until 20) filter And(_ > 10, _ % 2 == 1) 
res3: scala.collection.immutable.IndexedSeq[Int] = Vector(11, 13, 15, 17, 19) 

È facile scrivere nello stesso modo i combinatori Or e Not.