2017-01-03 16 views
0

Предположим, у меня есть два наблюдаемых сортированных двойника. Я хотел бы получить разницу между ними как наблюдаемую. Например:Как создать наблюдаемую разницу между двумя сортированными наблюдаемыми?

  1  2   4   
left: ──o───────o───────────o────/ 
      1 3 4 5 
right: ──o────o──o───o───/ 
        l2   r3 r5 
output: ──────────o───────────o────o─/ 

Необходимость реализации этого проста: Держите список пунктов на стороне, что вы еще не достигли и «испускают» элементы из другой стороны.

Каков канонический подход к этому в мире RFP? Я специально использую RxScala.

+0

Можете ли вы предоставить мраморную диаграмму, показывающую, когда испускаются значения из источников и как это приведет к наблюдаемому в результате? – Enigmativity

+0

@ Энигматичность. Я добавил мраморную диаграмму. HTH –

+0

Это красивая мраморная диаграмма. Как вы это сделали? Я все еще не могу понять правило. Вы можете объяснить это, пожалуйста? – Enigmativity

ответ

2

Так я бы сделал это в rxjava, подразумевая, что две наблюдаемые имеют одинаковую длину.

Observable<Integer> obs1 = Observable.just(1, 2, 4, 6); 
    Observable<Integer> obs2 = Observable.just(1, 3, 4, 5); 

    obs1.zipWith(obs2, (integer, integer2) -> { 
     if (!Objects.equals(integer, integer2)) { 
      return Observable.just(integer).concatWith(Observable.just(integer2)); 
     } else { 
      return Observable.empty(); 
     } 
    }) 
     .flatMap(observable -> observable) 
     .sorted() 
     .forEach(System.out::println); 

EDIT

Другой подход будет использовать коллекцию

Observable<Integer> obs1 = Observable.just(1, 2, 4); 
    Observable<Integer> obs2 = Observable.just(1, 3, 4, 5); 


    obs1.mergeWith(obs2) 
      .sorted() 
      .reduce(new ArrayList<Integer>(), (integers, integer) -> { 
       if (integers.contains(integer)) { 
        integers.remove(integer); 
       } else { 
        integers.add(integer); 
       } 
       return integers; 
      }) 
      .flatMapIterable(integers -> integers) 
      .forEach(System.out::println); 
+0

Здесь вы делаете два предположения: 1. Что наблюдаемые имеют одинаковую длину (я обновил вопрос, чтобы показать, что это не так); 2. То, что одна из наблюдаемых не может быть намного опережающей другую (они продвигаются с одинаковой скоростью). –

+0

Не будет ли этот новый подход блокировать, пока оба наблюдаемых не закончатся? –

+0

@OmervanKloeten нет, блокировки нет, все операторы производят неблокирующие наблюдаемые. –

1

Я не думаю, что есть много RxJava сделать что симметрическая разность «в реальном времени». .. Главным образом, потому что ваше исходное предположение (наблюдаемые сортируются) не могут быть сделаны родовыми операторами, поэтому немногие помогут вам в этом.

Однако вы можете попытаться запрограммировать пользовательский оператор для этой цели, вдохнув вдохновение из sequenceEqual: он внутренне продвигается шаг за шагом между двумя издателями для сравнения сравнений, так что это близко к тому, что вы хотите сделать.