Scala 基于条件的多重Akka源/流

Scala 基于条件的多重Akka源/流,scala,akka,akka-stream,Scala,Akka,Akka Stream,是否有一种方法可以根据某些外部条件将两个或多个Akka源或流多路复用?它可能是这样的: def cond:Boolean=??? val src1=Source.fromIterator(i1) val src2=Source.fromIterator(i2) val src3=Source.mux(src1、src2、cond) 根据cond结果src3应包含src1中的项目或src2中的项目,不得同时包含两者 我发现似乎是相反的操作。同时,所有扇入操作似乎都不支持条件合并。我不确定这是您需

是否有一种方法可以根据某些外部条件将两个或多个Akka源或流多路复用?它可能是这样的:

def cond:Boolean=???
val src1=Source.fromIterator(i1)
val src2=Source.fromIterator(i2)
val src3=Source.mux(src1、src2、cond)
根据
cond
结果
src3
应包含
src1
中的项目或
src2
中的项目,不得同时包含两者


我发现似乎是相反的操作。同时,所有扇入操作似乎都不支持条件合并。

我不确定这是您需要的,但您可以尝试以下操作:

def cond: Boolean = Random.nextBoolean()

val src1 = Source.fromIterator(() => LazyList.from(1).iterator)
val src2 = Source.fromIterator(() => LazyList.from(-1, -1).iterator)
val src3 = src1.zip(src2).map(pair => if (cond) pair._1 else pair._2)

src3.runForeach(println)
def mux[T](a: Source[T, Any], b: Source[T, Any])(cond: Int => Boolean): Source[T, Any] = {
  a.map((1, _)).merge(b.map((2, _)))
    .filter(t => cond(t._1))
    .map(_._2)
}
在一种情况下,输出开始于:

1
-2
3
4
-5
-6
7
-8
-9
10
...

如您所见,在本例中,我随机选择了两条流。

我建议如下:

def cond: Boolean = Random.nextBoolean()

val src1 = Source.fromIterator(() => LazyList.from(1).iterator)
val src2 = Source.fromIterator(() => LazyList.from(-1, -1).iterator)
val src3 = src1.zip(src2).map(pair => if (cond) pair._1 else pair._2)

src3.runForeach(println)
def mux[T](a: Source[T, Any], b: Source[T, Any])(cond: Int => Boolean): Source[T, Any] = {
  a.map((1, _)).merge(b.map((2, _)))
    .filter(t => cond(t._1))
    .map(_._2)
}
简单地说,它将标识符附加到每个源发出的元素(这里是1、2,但可以是任何元素),然后使用提供的
cond
函数进行过滤,以仅保留来自当前选定源的元素,然后映射回元素

我认为
zip
不是一个好主意,因为它“在所有输入都有一个元素可用时发出”,即,即使源a中有一个元素可用,并且您实际上希望切换到源a,
zip
也会等到B中有一个元素可用后再发出()


另一方面,
merge
将在任何源具有可用项时立即发出。

你是什么意思?您能添加示例输入和所需输出吗?不确定还需要什么样的示例。假设有两个独立的事件源,我想根据动态条件将它们组合在一起,只将其中一个发送到下游,而动态条件通常应该是事件本身的外部条件。例如
src1=Source(1,2,3)
,和
src2=Source(2,3,4)
cond=%2==0
那么
src3=Source(2,2,4)
你期待这样的事情吗?不,我的意思是,不一定。条件不必依赖于源中的项。比方说,我们有两个独立的无限流,A和B。比方说,每天下午5点到7点之间,我只想从流A接收消息,其余时间——从流B接收消息。事实上,现在我想起来了,也许有一种方法可以做到这一点,就是用一些id压缩每个源,然后将它们合并,然后根据此id筛选结果源。我不确定这是否是正确的方法。因此,请详细说明,就像您在上一篇评论中所做的那样,并创建,以便我们更好地理解如何回答您的问题。是的,这是我在另一篇评论中所考虑的,这确实是一个有价值的观察结果,
zip
可能并不完全正确。我只是想知道是否有什么现成的东西,因为多路复用似乎是相当常见的操作。另外,你能解释一下为什么你使用
通过(流)
而不是直接映射到
源代码上吗?
通过(流)
确实很愚蠢-删除它!我对Akka没有经验,另一个选择似乎是,但它看起来更复杂。