我不确定这是否可行,但我想基于某些条件对流进行分区,这取决于流的输出。我认为这是一个有用的例子。
我将创建一系列订单,我将流式传输,因为实际的用例是一个订单流,因此预先知道下一个订单是什么,甚至是完整的订单列表:
scala> case class Order(item : String, qty : Int, price : Double)
defined class Order
scala> val orders = List(Order("bike", 1, 23.34), Order("book", 3, 2.34), Order("lamp", 1, 9.44), Order("bike", 1, 23.34))
orders: List[Order] = List(Order(bike,1,23.34), Order(book,3,2.34), Order(lamp,1,9.44), Order(bike,1,23.34))
现在我想将这些订单分区/分组到一个包含重复订单的集合和另一个包含唯一订单的集合。所以在上面的例子中,当我强制流时,它应该创建两个流:一个带有两个自行车订单(因为它们是相同的)和另一个包含所有其他订单的流。
我尝试了以下内容:
创建了分区功能:
scala> def matchOrders(o : Order, s : Stream[Order]) = s.contains(o)
matchOrders: (o: Order, s: Stream[Order])Boolean
然后尝试将此应用于流:
scala> val s : (Stream[Order], Stream[Order]) = orders.toStream.partition(matchOrders(_, s._1))
我得到一个空指针异常,因为我猜s._1
最初是空的?我不确定。我尝试了其他方法,但我没有走得太远。有没有办法实现这种分区?
答案 0 :(得分:2)
这无论如何都行不通,因为当您处理副本时,第一个重复的Order
已经转到唯一的Stream
。
最好的方法是创建一个Map[Order, Boolean]
,告诉您Order
是否在原始订单列表中出现多次。
val matchOrders = orders.groupBy(identity).mapValues(_.size > 1)
val s : (Stream[Order], Stream[Order]) = orders.toStream.partition(matchOrders(_))
答案 1 :(得分:1)
请注意,您只能在流完成后知道订单没有重复项。因此标准Stream
构造函数要求您知道流是否为空,看起来它们不够懒惰:您必须强制原始流甚至开始构建无重复流。当然,如果你这样做,Helder Pereira的答案也适用。