之间假设我有以下数据流: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?
之间假设我有以下数据流: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?
使用与初始值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, ...
,然后过滤掉a
和b
得到
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');
好的。我发布这个以防其他人需要它的答案。与我上面介绍的稍有不同,只是为了便于理解。
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));
该代码更简单,使得它更容易遵循(即使它使用正则表达式)。
这里的问题是,对于去除数据流的'重复区域'的问题,它仍然不是一个真正的通用解决方案。它依靠将流转换为单个字符串,对字符串进行操作,然后将其转换回其他形式。如果任何人有任何想法如何以一般的方式来解决这个问题,我很乐意听到它。
优秀。我完全错过了使用扫描这种事情。 – melston