user1148417
user1148417

Reputation: 103

Scala for loop yield

I'm new to Scala so I'm trying to mess around with an example in Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition

  // Returns a row as a sequence
  def makeRowSeq(row: Int) =
    for (col <- 1 to 10) yield {
      val prod = (row * col).toString
      val padding = " " * (4 - prod.length)
      padding + prod
  }
  // Returns a row as a string
  def makeRow(row: Int) = makeRowSeq(row).mkString
  // Returns table as a string with one row per line
  def multiTable() = {
    val tableSeq = // a sequence of row strings
      for (row <- 1 to 10)
      yield makeRow(row)
    tableSeq.mkString("\n")
  }

When calling multiTable() the above code outputs:

  1   2   3   4   5   6   7   8   9  10
  2   4   6   8  10  12  14  16  18  20
  3   6   9  12  15  18  21  24  27  30
  4   8  12  16  20  24  28  32  36  40
  5  10  15  20  25  30  35  40  45  50
  6  12  18  24  30  36  42  48  54  60
  7  14  21  28  35  42  49  56  63  70
  8  16  24  32  40  48  56  64  72  80
  9  18  27  36  45  54  63  72  81  90
  10  20  30  40  50  60  70  80  90 100

This makes sense but if I try to change the code in multiTable() to be something like:

  def multiTable() = {
    val tableSeq = // a sequence of row strings
      for (row <- 1 to 10)
      yield makeRow(row) {
        2
      }
    tableSeq.mkString("\n")
  }

The 2 is being returned and changing the output. I'm not sure where it's being used though to manipulate the output and can't seem to find a similar example searching around here or Google. Any input would be appreciated!

Upvotes: 0

Views: 715

Answers (1)

Pranav Shukla
Pranav Shukla

Reputation: 2226

makeRow(row) {2}

and

makeRow(row)(2)

and

makeRow(row).apply(2)

are all equivalent.

makeRow(row) is of type List[String], each String representing one row. So effectively, you are picking character at index 2 from each row. That is why you are seeing 9 spaces and one 1 in your output.

  def multiTable() = {
    val tableSeq = // a sequence of row strings
      for (row <- 1 to 10)
        yield makeRow(row) {2}
    tableSeq.mkString("\n")
  }

is equivalent to applying a map on each row like

  def multiTable() = {
    val tableSeq = // a sequence of row strings
      for (row <- 1 to 10)
        yield makeRow(row)
    tableSeq.map(_(2)).mkString("\n")
  }

Upvotes: 1

Related Questions