NateH06
NateH06

Reputation: 3594

Cannot convert an iterator directly off of a for loop in Scala

I'm trying to use a for loop with an iterator to extract all the values of member fields of a case class and for use within my system, but need it to be in the format of a Seq[String]. I'm wondering why this works:

case class MyClass(field1:String, field2:Int){

  def toSeqString: Seq[String] = {
    val stringIter = for (field <- this.productIterator) yield {
      val changedField = // do some work on 'field'
     changedField.toString
    } 
    // stringIter is of type Iterator[String] at this point
    stringIter.toSeq
  }

}

But this doesn't:

case class MyClass(field1:String, field2:Int){

  def toSeqString: Seq[String] = {
    for (field <- this.productIterator) yield {
      val changedField = // do some work on 'field'
     changedField.toString
    }.toSeq // have also tried .to[collection.immutable.Seq]
  }

}

The error saying that the result of the second example is an Iterator[Seq[Char]], and not a Seq[String]. Why do I need to extract the result of my for loop to a val, rather than directly chain it off the completion of the for-yield loop? It would seem I'm doing the same thing?

Upvotes: 0

Views: 75

Answers (1)

Jean Logeart
Jean Logeart

Reputation: 53839

It is simply a parenthesis issue.

You want:

def toSeqString: Seq[String] = {
  (for (field <- this.productIterator) yield {
    val changedField = // do some work on 'field'
   changedField.toString
  }).toSeq
}

Note the extra parenthesis around for. Otherwise .toSeq is applied on the block after yield - therefore making the String a Seq[Char].

As a side note, you may want to simply do:

this.productIterator.map(p => ...).toSeq

Upvotes: 3

Related Questions