Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

for expressions versus foreach in Scala

I'm working my way through Programming in Scala, and though I'm tempted to look at things from the perspective of Python, I don't want to program "Python in Scala."

I'm not quite sure what to do as far as control flow goes: in Python, we use for x in some_iterable to death, and we love it. A very similar construct exists in Scala which Odersky calls a for expression, probably to distinguish it from the Java for loop. Also, Scala has a foreach attribute (I guess it would be an attribute, I don't know enough about Scala to name it correctly) for iterable data types. It doesn't seem like I can use foreach to do much more than call one function for each item in the container, though.

This leaves me with a few questions. First, are for expressions important/heavily used constructs in Scala like they are in Python, and second, when should I use foreach instead of a for expression (other than the obvious case of calling a function on each item of a container)?

I hope I'm not being terribly ambiguous or overbroad, but I'm just trying to grok some of the design/language fundamentals in Scala (which seems very cool so far).

like image 212
Rafe Kettler Avatar asked Dec 16 '10 23:12

Rafe Kettler


People also ask

What is foreach in Scala?

The foreach() method is utilized to apply the given function to all the elements of the map. Method Definition: def foreach(f: ((A, B)) => Unit): Unit. Return Type: It returns all the elements of the map after applying the given function to each of them.

Which expression is one way to iterate over a collection and generate a collection of each iteration's result in Scala?

In scala, for loop is known as for-comprehensions. It can be used to iterate, filter and return an iterated collection.

Which expression is one way to iterate over a collection in Scala?

A simple for loop that iterates over a collection is translated to a foreach method call on the collection. A for loop with a guard (see Recipe 3.3) is translated to a sequence of a withFilter method call on the collection followed by a foreach call.

How do you break a loop in Scala?

In Scala, we use a break statement to break the execution of the loop in the program. Scala programing language does not contain any concept of break statement(in above 2.8 versions), instead of break statement, it provides a break method, which is used to break the execution of a program or a loop.


1 Answers

python uses for in list comprehensions and generator expressions. Those are very similar to the scala for expression:

this is 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'] 

this is 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) 

Each construct can take a number of generators/iterators, apply filters expressions and yield a combined expression. In python the (expr for v1 in gen1 if expr1 for v2 in gen2 if expr2) is roughly equivalent to:

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

In scala for (v1 <- gen1 if expr1; v2 <- gen2 if expr2) yield expr is roughly equivalent to:

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

If you love the python for x in xs syntax, you'll likely love the scala for expression.

Scala has some additional syntax and translation twists. Syntax wise for can be used with braces so that you can put statements on separate lines. You can also perform value assignments.

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) 

Also v1 <- gen1 really performs a match case v1 => gen1. If there is no match those elements are ignored from the iteration.

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

I think for has an important place in the language. I can tell from the fact there is a whole chapter (23) about it in the book you're reading!

like image 69
huynhjl Avatar answered Sep 26 '22 05:09

huynhjl