所以我有以下类型:
case class Episode(
parentTconst: String,
seasonNumber: Int,
episodeNumber: Int
)
以及以下来源:
val episodeSource: Source[Episode, _] = FileIO.fromPath(Paths.get(myDataFilePath)).via(myDataParserToEpisode)
情节清单示例如下:
Seq(
Episode("gameof", 5, 8),
Episode("mentalist", 2, 4),
Episode("gameof", 5, 8),
Episode("mentalist", 1, 8),
Episode("rikiandmanual", 1, 8)
)
我正在尝试创建以下流程(不确定我是否是正确的签名,请告知,也许这是一个接收器,因为我正在消耗整个流来获取地图)
def gimmeThoseEpisodeGroups: Flow[Episode, Map[String, Seq[Episode]], _]
如果打印出来,看起来会像这样:
Map(
"gameof" -> Seq(Episode("gameof", 5, 8), Episode("gameof", 5, 8)),
"mentalist" -> Seq(Episode("mentalist", 2, 4), Episode("mentalist", 1, 8)),
"rikiandmanual" -> Seq(Episode("rikiandmanual", 1, 8))
)
我尝试了很多无效的组合。也许方法不正确。
我认为我应该使用groupBy。 另一件事是,也许我需要第一次使用流来获取组的键列表(或者找到一种方法来使用它一次但产生两个结果)。
我DuckDucked并发现了有关广播的信息,但是我还没有全神贯注。
def getGroupedByParentTConst: Flow[Episode, Map[String, Seq[Episode]], _] = Flow[Episode].groupBy(2, _.parentTconst)
但这失败了(无论如何,我觉得这不是正确的路径。
此外,我想我会提取parentTconst来使用它们作为分组键:
def getParentTConst: Flow[Episode, Set[String], _] = Flow[Episode].fold(Set.empty[String]) {
(right, left) => { right ++ Set(left.parentTconst) }
}
那行得通,但是我一直在努力弄清楚如何使用它们对我的原始资源进行分组...
此外,如果我使用键列表,那意味着我将必须消耗两个流才能进行分组。
我认为我有一个Duck问题,这不是一个真正困难的问题,但是由于我有使用akka流的约束,所以这并不是很简单。
任何帮助将不胜感激。
答案 0 :(得分:1)
您要实现的目标不能以流方式完成,因为创建所有分组情节的地图需要读取内存中的所有数据。没有任何中间结果。
如果您仍然希望这样做,可以按照与提议的方式类似的方式使用折叠
Flow[Episode].fold(Map.empty[String, List[Episode]]) { (map, e) ⇒
val key = e.parentTconst
map + (key → v :: map.getOrElse(key, Nil))
}
但是由于那将读取内存中的所有文件,因此您还可以节省使用akka流的麻烦,而只需使用scala.io.Source
。
如果您有太多数据无法容纳在内存中,则需要更改要求。