2015-08-08 7 views
2

Я не уверен, что это возможно, но я хочу разбить поток на основе некоторого условия, которое зависит от вывода потока. Я думаю, это будет иметь смысл.Разделение потока

я буду создавать кучу заказов, которые я потеку с фактическим случая использования является потоком заказов, поступающих так что не известен до фронта, что следующий заказ будет или даже полный список заказов:

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 изначально пуст? Я не уверен. Я пробовал другие способы, но я не очень далеко. Есть ли способ добиться этого разделения?

ответ

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(_)) 
+0

Как я уже объяснял, неизвестно, что такое весь список заказов, поэтому вы не можете написать свой предикат matchOrders, как у вас. Я создал приведенный выше список заказов, чтобы привести пример. Но вы сделали хороший вывод о первом порядке; Я тоже об этом подумал. Я думаю, мне может понадобиться создать какую-то рекурсивную структуру потока; Я экспериментирую с этим в данный момент –

1

Обратите внимание, что вы можете только знать, что заказ не имеет дубликатов после завершения потока. Поэтому, поскольку стандартные конструкторы Stream требуют, чтобы вы знали, что поток пуст, кажется, что они не ленивы: вам нужно заставить свой исходный поток даже начать создавать поток без дубликатов. И, конечно, если вы это сделаете, ответ Хелдера Перейры будет применен.

Смежные вопросы