Srinivas
Srinivas

Reputation: 2100

foreach loop in scala

In scala foreach loop if I have list

val a = List("a","b","c","d")

I can print them without a pattern matching like this

a.foreach(c => println(c))

But, if I have a tuple like this

val v = Vector((1,9), (2,8), (3,7), (4,6), (5,5))

why should I have to use

v.foreach{ case(i,j) => println(i, j) }
  1. a pattern matching case
  2. { brackets

Please explain what happens when the two foreach loops are executed.

Upvotes: 21

Views: 65979

Answers (4)

Alireza
Alireza

Reputation: 104640

Vector is working a bit differently, you using function literals using case...

In Scala, we using brackets{} which accept case...

{
  case pattern1 => "xxx"
  case pattern2 => "yyy"
}

So, in this case, we using it with foreach loop...

Print all values using the below pattern then:

val nums = Vector((1,9), (2,8), (3,7), (4,6), (5,5))

nums.foreach {
    case(key, value) => println(s"key: $key, value: $value")
}

Also you can check other loops like for loop as well if you think this is not something which you are comfortable with...

Upvotes: 1

grnc
grnc

Reputation: 527

According to http://alvinalexander.com/scala/iterating-scala-lists-foreach-for-comprehension:

val names = Vector("Bob", "Fred", "Joe", "Julia", "Kim")

for (name <- names)
    println(name)

Upvotes: 6

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149518

You don't have to, you choose to. The problem is that the current Scala compiler doesn't deconstruct tuples, you can do:

v.foreach(tup => println(tup._1, tup._2))

But, if you want to be able to refer to each element on it's own with a fresh variable name, you have to resort to a partial function with pattern matching which can deconstruct the tuple.

This is what the compiler does when you use case like that:

def main(args: Array[String]): Unit = {
  val v: List[(Int, Int)] = scala.collection.immutable.List.apply[(Int, Int)](scala.Tuple2.apply[Int, Int](1, 2), scala.Tuple2.apply[Int, Int](2, 3));
  v.foreach[Unit](((x0$1: (Int, Int)) => x0$1 match {
    case (_1: Int, _2: Int)(Int, Int)((i @ _), (j @ _)) => scala.Predef.println(scala.Tuple2.apply[Int, Int](i, j))
  }))
}

You see that it pattern matches on unnamed x0$1 and puts _1 and _2 inside i and j, respectively.

Upvotes: 17

pJunger
pJunger

Reputation: 63

To answer #2: You can only use case in braces. A more complete answer about braces is located here.

Upvotes: 2

Related Questions