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

我试过 mapflatMap,但它要么创建迭代器的迭代器,要么创建组合元素。

你有点纠结了;这比你想象的要容易得多! :-)

请记住,对于某些容器类型 C 持有类型 A 的物品(即 C[A]),如果你想获得 C[B](即持有物品的容器类型 B) 然后只需提供 AB 的方法作为 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
}