web-dev-qa-db-fra.com

Trouver un élément qui correspond au prédicat dans Scala

J'essaie de rechercher dans une collection scala un élément de la liste qui correspond à un prédicat. Je n'ai pas nécessairement besoin de la valeur de retour, je vérifie simplement si la liste en contient.

En Java, je pourrais faire quelque chose comme:

for ( Object item : collection ) {
    if ( condition1(item) && condition2(item) ) {
       return true;
    }
}
return false;

Dans Groovy, je peux faire quelque chose comme:

return collection.find { condition1(it) && condition2(it) } != null

Quelle est la manière idiomatique de faire cela à Scala? Je pourrais bien sûr convertir le style de boucle Java en Scala, mais j’ai l’impression qu’il existe un moyen plus fonctionnel de le faire.

43
Jeff Storey

Utiliser le filtre: 

scala> val collection = List(1,2,3,4,5)
collection: List[Int] = List(1, 2, 3, 4, 5)

// take only that values that both are even and greater than 3 
scala> collection.filter(x => (x % 2 == 0) && (x > 3))
res1: List[Int] = List(4)

// you can return this in order to check that there such values
scala> res1.isEmpty
res2: Boolean = false

// now query for elements that definitely not in collection
scala> collection.filter(x => (x % 2 == 0) && (x > 5))
res3: List[Int] = List()

scala> res3.isEmpty
res4: Boolean = true

Mais si tout ce dont vous avez besoin est de vérifier, utilisez exists:

scala> collection.exists( x => x % 2 == 0 )
res6: Boolean = true
49
om-nom-nom

Test si le prédicat de correspondance de valeur existe

Si vous souhaitez simplement vérifier si une valeur existe, vous pouvez le faire avec .... exists

scala> val l=(1 to 4) toList
l: List[Int] = List(1, 2, 3, 4)

scala> l exists (_>5)
res1: Boolean = false

scala> l exists (_<2)
res2: Boolean = true

scala> l exists (a => a<2 || a>5)
res3: Boolean = true

Autres méthodes (certaines basées sur les commentaires):

Compter les éléments correspondants

Compter les éléments qui satisfont le prédicat (et vérifier si nombre> 0)

scala> (l count (_ < 3)) > 0
res4: Boolean = true

Retour du premier élément correspondant

Trouvez le premier élément qui satisfait le prédicat (comme suggéré par Tomer Gabel et Luigi Plinge, cela devrait être plus efficace car il retourne dès qu'il trouve un élément qui satisfait le prédicat, plutôt que de parcourir la liste entière de toute façon)

scala> l find (_ < 3)
res5: Option[Int] = Some(1) 

// also see if we found some element by
// checking if the returned Option has a value in it
scala> l.find(_ < 3) isDefined
res6: Boolean = true

Test si la valeur exacte existe

Pour le cas simple où nous vérifions en fait seulement si un élément spécifique est dans la liste

scala> l contains 2
res7: Boolean = true
53
Paolo Falabella

La méthode scala consisterait à utiliser exists:

collection.exists(item => condition1(item) && condition2(item))

Et depuis Java 8, vous pouvez utiliser anyMatch:

collection.stream().anyMatch(item -> condition1(item) && condition2(item));

ce qui est beaucoup mieux qu'une plaine pour ou pour chaque.

0