2017-05-28 78 views
0

之間假設我有以下數據流:reactivex重複跳過

1, 2, 3, a, 5, 6, b, 7, 8, a, 10, 11, b, 12, 13, ... 

我想不管他們有多少次出現過濾「a」和「B」(含)之間的所有內容。所以上面的結果將是:

1, 2, 3, 7, 8, 12, 13, ... 

我怎樣才能做到這一點與ReactiveX?

回答

2

使用與初始值b掃描轉

1, 2, 3, a, 5, 6, b, 7, 8, a, 10, 11, b, 12, 13, ...

b, 1, 2, 3, a, a, a, b, 7, 8, a, a, a, b, 12, 13, ...

,然後過濾掉ab得到

1, 2, 3, 7, 8, 12, 13, ...

在僞代碼

values.scan('b', (s, v) -> if (v == 'a' || v == 'b' || s != 'a') v else s). filter(v -> v != 'a' && v != 'b');

+0

優秀。我完全錯過了使用掃描這種事情。 – melston

0

好的。我發佈這個以防其他人需要它的答案。與我上面介紹的稍有不同,只是爲了便於理解。

List<String> values = new List<string>() 
{ 
    "1", "2", "3", 
    "a", "5", "6", "b", 
    "8", "9", "10", "11", 
    "a", "13", "14", "b", 
    "16", "17", "18", "19", 
    "a", "21", "22", "b", 
    "24" 
}; 

var aa = 
    // Create an array of CSV strings split on the terminal sigil value 
    String.Join(",", values.ToArray()) 
    .Split(new String[] { "b," }, StringSplitOptions.None) 

    // Create the observable from this array of CSV strings 
    .ToObservable() 

    // Now create an Observable from each element, splitting it up again 
    // It is no longer a CSV string but the original elements up to each terminal value 
    .Select(s => s.Split(',').ToObservable() 
     // From each value in each observable take those elements 
     // up to the initial sigil 
     .TakeWhile(s1 => !s1.Equals("a"))) 

    // Concat the output of each individual Observable - in order 
    // SelectMany won't work here since it could interleave the 
    // output of the different Observables created above. 
    .Concat(); 

aa.Subscribe(s => Console.WriteLine(s)); 

此打印出:

1 
2 
3 
8 
9 
10 
11 
16 
17 
18 
19 
24 

這是一個有點令人費解更比我想要的,但它的工作原理。

編輯17年6月3日:

我竟然發現我的情況更清潔的解決方案。

List<String> values = new List<string>() 
{ 
    "1", "2", "3", 
    "a", "5", "6", "b", 
    "8", "9", "10", "11", 
    "a", "13", "14", "b", 
    "16", "17", "18", "19", 
    "a", "21", "22", "b", 
    "24" 
}; 

string lazyABPattern = @"a.*?b"; 
Regex abRegex = new Regex(lazyABPattern); 

var bb = values.ToObservable() 
    .Aggregate((s1, s2) => s1 + "," + s2) 
    .Select(s => abRegex.Replace(s, "")) 
    .Select(s => s.Split(',').ToObservable()) 
    .Concat(); 
bb.Subscribe(s => Console.WriteLine(s)); 

該代碼更簡單,使得它更容易遵循(即使它使用正則表達式)。

這裏的問題是,對於去除數據流的'重複區域'的問題,它仍然不是一個真正的通用解決方案。它依靠將流轉換爲單個字符串,對字符串進行操作,然後將其轉換回其他形式。如果任何人有任何想法如何以一般的方式來解決這個問題,我很樂意聽到它。