style guide course scala collections idiomatic

guide - Encontrar un elemento que coincida con el predicado en Scala



scala guide style (4)

Estoy tratando de buscar en una colección scala un elemento en una lista que coincida con algún predicado. No necesito necesariamente el valor de retorno, solo pruebo si la lista lo contiene.

En Java, podría hacer algo como:

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

En Groovy, puedo hacer algo como:

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

¿Cuál es la forma idiomática de hacer esto en Scala? Por supuesto, podría convertir el estilo de bucle Java a Scala, pero siento que hay una forma más funcional de hacerlo.


Prueba si existe un predicado de coincidencia de valores

Si solo está interesado en probar si existe un valor, puede hacerlo con ... 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

Otros métodos (algunos basados ​​en comentarios):

Contando elementos coincidentes

Cuente elementos que satisfagan el predicado (y verifique si cuenta> 0)

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

Devolver el primer elemento coincidente

Encuentre el primer elemento que satisfaga el predicado (como lo sugirieron Tomer Gabel y Luigi Plinge, esto debería ser más eficiente porque regresa tan pronto como encuentra un elemento que satisface el predicado, en lugar de atravesar la Lista completa de todos modos)

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

Prueba si existe un valor exacto

Para el caso simple donde en realidad solo estamos verificando si un elemento específico está en la lista

scala> l contains 2 res7: Boolean = true


La forma de escala sería usar exists :

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

Y desde java 8 puedes usar anyMatch :

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

que es mucho mejor que una llanura para o foreach.


Usar filtro:

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

Pero si todo lo que necesita es verificar que el uso exists :

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


Filtra y existe palabras clave para obtener los valores coincidentes de las listas

val values = List(1,2,3,4,5,6,7,8,9,10,....,1000) //List -1 val factors= List(5,7) // List -2 //To get the factors of List-2 from List-1 values .filter(a => factors.exists(b => a%b == 0)) //Apply different logic for our convenience

El código dado ayuda a obtener los valores coincidentes de 2 listas diferentes