2017-05-28 84 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)); 

该代码更简单,使得它更容易遵循(即使它使用正则表达式)。

这里的问题是,对于去除数据流的'重复区域'的问题,它仍然不是一个真正的通用解决方案。它依靠将流转换为单个字符串,对字符串进行操作,然后将其转换回其他形式。如果任何人有任何想法如何以一般的方式来解决这个问题,我很乐意听到它。