Akka流减少到更小的流

时间:2017-09-10 11:55:11

标签: scala akka akka-stream reactive-streams

我有一个有序的数据流

A A A B B C C C C ... (very long)

我想将其转换为表格(项目,计数)中的聚合流:

(A, 3) (B, 2) (C, 4)

我可以在Akka Streams中使用哪些运营商?

Source.fromPublisher(publisher)
    .aggregateSomehow()  // ?
    .runWith(sink)

我调查了.groupBy,但要求我事先知道类别的数量,而不是。此外,我相信它会让所有群体都记忆犹新。我应该能够在处理完之后丢弃(A,3)并释放它消耗的资源。

修改This question要求使用类似功能但使用SubFlows。但是,似乎不需要使用SubFlow,因为我有一个使用statefulMapConcat组合器的解决方案。

1 个答案:

答案 0 :(得分:1)

一种选择是使用statefulMapConcat组合子:

Source(List("A", "A", "B", "B", "B", "C", "C", ""))
      .statefulMapConcat({ () =>
        var lastChar = ""
        var count = 0

        char => if(lastChar == char) {
            count += 1
            List.empty
          } else {
            val charCount = (lastChar, count)
            lastChar = char
            count = 1
            List(charCount)
          }
      })
    .runForeach(println)

但是,需要在输入流中附加一个元素来标记结尾。

输出:

(,0)
(A,2)
(B,3)
(C,2)

感谢@chunjef提出的意见建议