4

I have a method like this:

def close(): Unit = {
    things.foreach {
      case (attr1, attr2) =>
        File.<do_something>(attr1, attr2)
    }
  }

What kind of structure is this? I know it's iterating through all the things which is a map if <attr1, attr2>. Can I access the thing itself? What if I also wanted to pattern match on the class/type of the thing. How can I do this?

Jwan622
  • 11,015
  • 21
  • 88
  • 181

2 Answers2

10

foreach is a method which takes a function f: A => U as an argument.

  @inline final override def foreach[U](f: A => U) {
    var these = this
    while (!these.isEmpty) {
      f(these.head)
      these = these.tail
    }
  }

Example below

scala> List(1, 2, 3).foreach { elem => println(s"my elem is $elem") }
my elem is 1
my elem is 2
my elem is 3

Now, nice thing about scala is that you can "pattern match" based on value of element. Think of it like if else but also with capability of deconstructing your input. (read about patmat in programming)

scala> List(1, "data", 3).foreach { 
         case elem: String => println(s"my elem is $elem") 
         case _ => println("something else")
       }
something else
my elem is data
something else

The second example is whats happening in your example. you are pattern matching each element to case (attr1, attr2), meaning each element is deconstructed to (attr1, attr2)

More example,

scala> Map(1 -> "order 1", 2 -> "order 2", 3 -> "order 3").foreach { 
            case (key, value) => println(value)
       }
order 1
order 2
order 3

scala> List((1, "order 1"), (2, "order 2"), (3, "order 3")).foreach { 
            case (key, value) => println(value)
       }
order 1
order 2
order 3

Without "pattern match" you could simply provide a function,

scala> Map(1 -> "order 1", 2 -> "order 2", 3 -> "order 3").foreach { 
             keyValue => println(keyValue._2)
       }
order 1
order 2
order 3
prayagupa
  • 30,204
  • 14
  • 155
  • 192
1

This is applying an anonymous function which has two arguments to every element in things.

In the case that things is a Map[A, B], it will apply File.<do_something> to the key and value of each pair in the map assuming <do_something>'s first argument is of type A and the second argument is of type B.

erip
  • 16,374
  • 11
  • 66
  • 121