Flatmap 合并一个内部迭代器
Flatmap merging an internal iterator
我正在尝试将 Iterator[String]
转换为 Iterator[CustomClass]
,其中 CustomClass
是不言自明的,这里不需要太多细节。
工作流程是:
Iterator[String] -> Iterator[Array[Byte]] -> Iterator[CustomClass]
我目前拥有的:
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 }
有了这个,我的最终结果是一个 Iterator[CustomClass]
,它包含一个元素,其中所有输入字节数组组合成一个字节数组。因此,如果我使用具有两个元素的字符串迭代器调用 extractAsCustomClass
,最终结果将是 Iterator[CustomClass]
,它只有一个组合元素。
使用上面带有两个元素的输入字符串迭代器的示例,我想要一个包含两个 CustomClass
元素的 Iterator[CustomClass]
,其中每个字符串都来自
String -> Array[Byte] -> CustomClass
我试过 map
和 flatMap
,但它要么创建迭代器的迭代器,要么创建组合元素。
你有点纠结了;这比你想象的要容易得多! :-)
请记住,对于某些容器类型 C
持有类型 A
的物品(即 C[A]
),如果你想获得 C[B]
(即持有物品的容器类型 B
) 然后只需提供 从 A
到 B
的方法作为 map
的参数。您根本不需要担心外部容器类型 C
.
所以在你的情况下,你需要提供的功能只是:
private def toByteArray(data: String): Array[Byte]
private def toCustomClass(blob: Array[Byte]): CustomClass
请注意他们是如何在任何地方不提及 Iterator
的。一个很大的好处 - 它们更有用,因此 re-usable。
所以对于一个完整的工作(和工作!)示例:
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)
}
现在你的提取函数就是:
def extractAsCustomClass(strings: Iterator[String]): Iterator[CustomClass] = {
val byteArrayIt = strings.map(toByteArray)
val customClassIt = byteArrayIt.map(toCustomClass)
customClassIt
}
我正在尝试将 Iterator[String]
转换为 Iterator[CustomClass]
,其中 CustomClass
是不言自明的,这里不需要太多细节。
工作流程是:
Iterator[String] -> Iterator[Array[Byte]] -> Iterator[CustomClass]
我目前拥有的:
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 }
有了这个,我的最终结果是一个 Iterator[CustomClass]
,它包含一个元素,其中所有输入字节数组组合成一个字节数组。因此,如果我使用具有两个元素的字符串迭代器调用 extractAsCustomClass
,最终结果将是 Iterator[CustomClass]
,它只有一个组合元素。
使用上面带有两个元素的输入字符串迭代器的示例,我想要一个包含两个 CustomClass
元素的 Iterator[CustomClass]
,其中每个字符串都来自
String -> Array[Byte] -> CustomClass
我试过 map
和 flatMap
,但它要么创建迭代器的迭代器,要么创建组合元素。
你有点纠结了;这比你想象的要容易得多! :-)
请记住,对于某些容器类型 C
持有类型 A
的物品(即 C[A]
),如果你想获得 C[B]
(即持有物品的容器类型 B
) 然后只需提供 从 A
到 B
的方法作为 map
的参数。您根本不需要担心外部容器类型 C
.
所以在你的情况下,你需要提供的功能只是:
private def toByteArray(data: String): Array[Byte]
private def toCustomClass(blob: Array[Byte]): CustomClass
请注意他们是如何在任何地方不提及 Iterator
的。一个很大的好处 - 它们更有用,因此 re-usable。
所以对于一个完整的工作(和工作!)示例:
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)
}
现在你的提取函数就是:
def extractAsCustomClass(strings: Iterator[String]): Iterator[CustomClass] = {
val byteArrayIt = strings.map(toByteArray)
val customClassIt = byteArrayIt.map(toCustomClass)
customClassIt
}