I'm trying to convert an Iterator[String]
to Iterator[CustomClass]
, where CustomClass
is self-explanatory and doesn't need to have much detail here.
The workflow is:
Iterator[String] -> Iterator[Array[Byte]] -> Iterator[CustomClass]
What I have so far:
def extractAsCustomClass(strings: Iterator[String]): Iterator[CustomClass] = {
val byteArrayIt = strings.flatMap(toByteArrayIterator)
val customClassIt = byteArrayIt.flatMap(toCustomClassIterator)
customClassIt
}
private def toByteArrayIterator(data: String): Iterator[Array[Byte]] = { // converts to byte array }
private def toCustomClassIterator(blob: Array[Byte]): Iterator[CustomClass] = { // converts to custom class }
With this, my end result is an Iterator[CustomClass]
that contains one element where all the input byte arrays were combined into one byte array. So if I call extractAsCustomClass
with a String iterator that has two elements, the end result would be Iterator[CustomClass]
which only has one, combined element.
Using the example above of an input String iterator with two elements, I instead want an Iterator[CustomClass]
that contains two CustomClass
elements, where each String has gone from
String -> Array[Byte] -> CustomClass
I've tried playing around with map
and flatMap
but it either creates iterators of iterators or a combined element.
CodePudding user response:
You've got yourself a little bit tangled up; it's way easier than you think it is! :-)
Remember that for some container type C
holding items of type A
(i.e. C[A]
) if you want to get a C[B]
(i.e. a container holding items of type B
) then just supply the way to get from A
to B
as the argument to map
. You don't need to worry about the outer container type C
at all.
So in your case, the functions you need to supply would just be:
private def toByteArray(data: String): Array[Byte]
private def toCustomClass(blob: Array[Byte]): CustomClass
Notice how they don't mention Iterator
anywhere. A great benefit - they're much more useful and re-usable as a result.
So for a complete worked (and working!) example:
case class CustomClass(foo: String)
private def toByteArray(data: String): Array[Byte] = {
// converts to byte array
data.getBytes
}
private def toCustomClass(blob: Array[Byte]): CustomClass = {
// converts to custom class
val s = new String(blob)
CustomClass(s)
}
Now your extract function is just:
def extractAsCustomClass(strings: Iterator[String]): Iterator[CustomClass] = {
val byteArrayIt = strings.map(toByteArray)
val customClassIt = byteArrayIt.map(toCustomClass)
customClassIt
}