for array scala loops foreach

for array scala



para expresiones versus foreach en Scala (5)

Con su soporte para iteración anidada, filtros y transformación, diría que Scala''s es uno de los puntos fuertes del lenguaje y muy central. Tiendo a favorecerlo sobre el uso de foreach , map y filter .

Estoy trabajando en la Programación en Scala , y aunque estoy tentado de ver las cosas desde la perspectiva de Python, no quiero programar "Python en Scala".

No estoy seguro de qué hacer en lo que respecta al flujo de control: en Python, usamos for x in some_iterable hasta la muerte, y nos encanta. Existe una construcción muy similar en Scala que Odersky llama una expresión , probablemente para distinguirla del bucle de Java for. Además, Scala tiene un atributo foreach (supongo que sería un atributo, no sé lo suficiente sobre Scala para nombrarlo correctamente) para tipos de datos iterables. Sin embargo, no parece que pueda usar foreach para hacer mucho más que llamar a una función para cada elemento en el contenedor.

Esto me deja con algunas preguntas. En primer lugar, están las expresiones construcciones importantes / muy utilizadas en Scala como en Python, y segundo, ¿cuándo debería usar foreach lugar de una expresión for (que no sea el caso obvio de invocar una función en cada elemento de un contenedor)?

Espero que no sea terriblemente ambiguo o demasiado amplio, pero estoy tratando de asimilar algunos de los fundamentos del diseño / lenguaje en Scala (lo cual parece muy bueno hasta ahora).


El foreach es un estilo funcional, mientras que el for es un estilo imperativo. Si alguna vez has hecho algún ceceo o esquema, ya estás familiarizado con la programación funcional. Si no lo has hecho, puede ser un poco confuso al principio. Lo primero que haría es leer sobre la sintaxis de cierre, que son funciones anónimas que se pasan a cosas como foreach. Una vez que entiendas que todo tendrá más sentido.


Python se utiliza en la lista de comprensiones y expresiones de generador. Esos son muy similares a la escala for expresión:

esto es python

>>> letters = [''a'', ''b'', ''c'', ''d''] >>> ints = [0, 1, 2, 3] >>> [l + str(i) for l in letters for i in ints if i % 2 == 0] [''a0'', ''a2'', ''b0'', ''b2'', ''c0'', ''c2'', ''d0'', ''d2'']

esto es Scala

scala> val letters = List(''a'', ''b'', ''c'', ''d'') scala> val ints = List(0, 1, 2, 3) scala> for (l <- letters; i <- ints if i % 2 == 0) yield l.toString + i res0: List[java.lang.String] = List(a0, a2, b0, b2, c0, c2, d0, d2)

Cada construcción puede tomar un número de generadores / iteradores, aplicar expresiones de filtros y producir una expresión combinada. En python, (expr for v1 in gen1 if expr1 for v2 in gen2 if expr2) es aproximadamente equivalente a:

for v1 in gen1: if expr1: for v2 in gen2: if expr2: yield expr

En scala for (v1 <- gen1 if expr1; v2 <- gen2 if expr2) yield expr es más o menos equivalente a:

gen1.withFilter(expr1).flatMap(v1 => gen2.withFilter(expr2).map(v2 => expr))

Si amas la sintaxis de for x in xs python, es probable que te guste la expresión scala.

Scala tiene algunos giros de sintaxis y traducción adicionales. La sintaxis sabia se puede usar con llaves para que pueda poner declaraciones en líneas separadas. También puede realizar asignaciones de valores.

val res = for { i <- 1 to 20; i2 = i*i j <- 1 to 20; j2 = j*j k <- 1 to 20; k2 = k*k if i2 + j2 == k2 } yield (i, j, k)

También v1 <- gen1 realmente realiza un case v1 => gen1 coincidencia case v1 => gen1 . Si no hay coincidencia, esos elementos se ignoran de la iteración.

scala> val list = List(Some(1), None, Some(2)) scala> for (Some(i) <- list) yield i res2: List[Int] = List(1, 2)

Creo que tiene un lugar importante en el lenguaje. ¡Puedo decir que hay un capítulo entero (23) al respecto en el libro que estás leyendo!


Sí, Scala para las comprensiones (como se les conoce comúnmente) se usan mucho, pero en realidad son solo azúcar sintáctico para una combinación particular de métodos, y muchos prefieren llamar estos métodos directamente en lugar de usar el azúcar sintáctico.

Para comprender mejor Scala por comprensión, consulte esta pregunta . En particular, verá que for (x <- xs) f(x) es lo mismo que xs.foreach(x => f(x)) .

Ahora, mencionas que no te parece muy útil con el método foreach , pero señalaré que casi todos los métodos de las colecciones Scala se implementan (o se pueden) con solo foreach . Consulte la documentación de Traversable : todos sus métodos pueden implementarse solo con foreach .

Tenga en cuenta que el yield de Scala no guarda ninguna semejanza con el yield de Python; también puede buscar that pregunta.


Sus preguntas son en gran parte respondidas por lo siguiente:

Scala''s For Comprehensions

Rendimiento de Scala

Para resumir: es en gran medida estilística. Personalmente, estoy a favor de la metodología funcional, pero prefiero la concisión de las comprensiones cuando se trata de bucles anidados.