2016-02-26 2 views
1

я ищу Observable.Window как оператор с открытия окна выбораРасщепление Наблюдаемые в окна

В качестве примера мы можем взять последовательность натуральных чисел. мне интересно, как разделить эту последовательность в окно, чтобы каждое новое окно начинается, если число больше, чем 4 или размер окна достигло 3

Входной последовательность IObservable<int> последовательности Выхода IObservable<IObservable<int>>

Последовательность 1 2 5 3 1 1 2 3 1 5 0 будет производить окна 1 2; 5 3 1; 1 2 3; 1; 5 0

+0

Если '1, 2, 3, 5' производить окна' 1 2 3; 5' или '1 2 3; ; 5'? (Обратите внимание на пустое окно) – Lukazoid

+0

Извините за то, что вы не прояснили ';' - был разделителем между желаемыми последовательностями – bublegumm

+0

Я понимаю это, но выполняю оба ответа с входной последовательностью 1,2,3,5, и они дают разные результаты. – Lukazoid

ответ

2

Использование C# это работает:

var observable = 
    source 
     .Concat(Observable.Return(-1)) 
     .Publish(sp => 
      sp.Zip(sp.Skip(1), (x0, x1) => new { x0, x1 }) 
       .Publish(zsp => 
        zsp 
         .Window(zsp.Where(x => x.x1 >= 4)) 
         .Select(xs => xs.Select(x => x.x0).Window(3)) 
         .Merge())); 

Я получаю этот результат:

result

+0

Какой инструмент вы используете для визуализации результатов «Наблюдаемые»? – supertopi

+0

@supertopi - это [LINQPad] (https://www.linqpad.net/). – Enigmativity

1

В соответствии мой комментарий по этому вопросу я не уверен, является ли последовательность 1, 2, 3, 5 должна производить окна 1 2 3 | 5 или 1 2 3 | | 5 (см. Пустое окно, которое дает результат ответа Enigmativity). Мой ответ не дает пустое окно:

public static IObservable<IObservable<T>> Window<T>(this IObservable<T> source, Func<T, bool> predicate, int maximumWindowSize) 
{ 
    return Observable.Create<IObservable<T>>(obs => 
    { 
     var currentWindow = new Subject<T>(); 
     obs.OnNext(currentWindow); 

     var count = 0; 

     return source.Subscribe(x => 
     { 
      if (count == maximumWindowSize || predicate(x)) 
      { 
       count = 0; 
       currentWindow.OnCompleted(); 
       currentWindow = new Subject<T>(); 
       obs.OnNext(currentWindow); 
      } 
      currentWindow.OnNext(x); 
      count++; 
     }, obs.OnError,() => 
     { 
      obs.OnCompleted(); 
      currentWindow.OnCompleted(); 
     }); 
    }); 
} 

Это может быть использовано как так:

var windows = source.Window(x => x > 4, 3); 
+0

Я проверил шахту и не получил пустой результат посередине. Можете ли вы опубликовать код, который вы использовали для проверки моего кода? – Enigmativity

+0

http://share.linqpad.net/klomqj.linq - это код, который я запускал. – Lukazoid

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