C# 反应性试验,以观察不同和重复的值
我编写测试是为了观察C# 反应性试验,以观察不同和重复的值,c#,system.reactive,rx.net,C#,System.reactive,Rx.net,我编写测试是为了观察Distinc操作 public class Test: ReactiveTest { [Fact] public void Observe_distint_nonDistinc() { var scheduler = new TestScheduler(); var source = scheduler.CreateHotObservable( OnNext(100, "a"),
Distinc
操作
public class Test: ReactiveTest {
[Fact]
public void Observe_distint_nonDistinc() {
var scheduler = new TestScheduler();
var source = scheduler.CreateHotObservable(
OnNext(100, "a"),
OnNext(110, "b"),
OnNext(200, "a"),
OnNext(220, "c"),
OnNext(221, "a")
);
var results = scheduler.CreateObserver<string>();
source.Distinct().Subscribe(results);
scheduler.AdvanceBy(1000);
results.Messages.AssertEqual(OnNext(100,"a"),OnNext(110,"b"),OnNext(220,"c"));
}
}
公共类测试:ReactiveTest{
[事实]
公共无效观察\u区分\u不区分(){
var scheduler=newtestscheduler();
var source=scheduler.CreateHotObservable(
OnNext(100,“a”),
OnNext(110,“b”),
OnNext(200,“a”),
OnNext(220,“c”),
OnNext(221,“a”)
);
var results=scheduler.CreateObserver();
source.Distinct().Subscribe(结果);
调度程序提前(1000);
结果.Messages.AssertEqual(OnNext(100,“a”)、OnNext(110,“b”)、OnNext(220,“c”);
}
}
测试通过了,但是我不确定如何同时观察副本。我尝试了一些与
Publish
和combinelateest
的组合,但是我觉得它们不值得一提。我的replicate
流应该只有两项OnNext(200,“a”)、OnNext(221,“a”)
以下是一个完整的解决方案:
[Fact]
public void ObserveDistinctNonDistinct()
{
var scheduler = new TestScheduler();
var source = scheduler.CreateHotObservable(
OnNext(100, "a"),
OnNext(110, "b"),
OnNext(200, "a"),
OnNext(220, "c"),
OnNext(221, "a")
).Publish();
var distinctResults = scheduler.CreateObserver<string>();
source
.Distinct()
.Subscribe(distinctResults);
var nonDistinctResults = scheduler.CreateObserver<string>();
(from letter in source
group letter by letter
into groupedLetters
from count in groupedLetters
.Window(Observable.Never<string>())
.SelectMany(ol =>
ol.Scan(0, (c, _) => ++c))
where count > 1
select groupedLetters.Key)
.Distinct()
.Subscribe(nonDistinctResults);
source.Connect();
scheduler.AdvanceBy(1000);
distinctResults.Messages.AssertEqual(OnNext(100, "a"), OnNext(110, "b"), OnNext(220, "c"));
nonDistinctResults.Messages.AssertEqual(OnNext(200, "a"));
}
[事实]
public void observeDistinctNondistict()
{
var scheduler=newtestscheduler();
var source=scheduler.CreateHotObservable(
OnNext(100,“a”),
OnNext(110,“b”),
OnNext(200,“a”),
OnNext(220,“c”),
OnNext(221,“a”)
).Publish();
var distinctResults=scheduler.CreateObserver();
来源
.Distinct()
.订阅(distinctResults);
var nonDistinctResults=scheduler.CreateObserver();
(来源于信函)
逐字分组
分组
从分组字母计数
.Window(可观察的.Never())
.SelectMany(ol=>
ol.扫描(0,(c,)=>++c))
其中计数>1
选择groupedLetters.Key)
.Distinct()
.认购(无差别结果);
source.Connect();
调度程序提前(1000);
AssertEqual(OnNext(100,“a”)、OnNext(110,“b”)、OnNext(220,“c”);
无差别结果.消息.资产质量(OnNext(200,“a”);
}
在第二次出现任何重复项时匹配
使用方法语法:
source
.GroupBy(s => s)
.SelectMany(g =>
g.Window(Observable.Never<string>())
.SelectMany(ol =>
ol.Scan(0, (c, _) => ++c))
.Where(l => l > 1)
.Select(_ => g.Key))
.Distinct()
.Subscribe(nonDistinctResults);
源代码
.GroupBy(s=>s)
.SelectMany(g=>
g、 窗口(Observable.Never())
.SelectMany(ol=>
ol.扫描(0,(c,)=>++c))
.其中(l=>l>1)
.选择(=>g.Key))
.Distinct()
.认购(无差别结果);
直到我找到一种更快的实现方法,我想发布我的自定义CollectDublicates
扩展方法。现在考试如预期的那样通过了
public class Test : ReactiveTest {
[Fact]
public void Observe_distint_nonDistinc() {
var scheduler = new TestScheduler();
var source = scheduler.CreateHotObservable(
OnNext(100, "a"),
OnNext(110, "b"),
OnNext(200, "a"),
OnNext(220, "c"),
OnNext(221, "a")
).Publish();
var distinnctResults = scheduler.CreateObserver<string>();
source.Distinct().Subscribe(distinnctResults);
var duplicatesResults = scheduler.CreateObserver<string>();
source.CollectDuplicates().Subscribe(duplicatesResults);
source.Connect();
scheduler.AdvanceBy(1000);
distinnctResults.Messages.AssertEqual(OnNext(100, "a"), OnNext(110, "b"), OnNext(220, "c"));
duplicatesResults.Messages.AssertEqual(OnNext(200,"a"),OnNext(221,"a"));
}
}
public static class RxEx{
class DubplicateCollector<T> : IEqualityComparer<T> {
readonly Subject<T> _matches = new Subject<T>();
public IObservable<T> Matches => _matches;
public bool Equals(T x, T y) {
var @equals = x.Equals(y);
if (equals)
_matches.OnNext(x);
return @equals;
}
public int GetHashCode(T obj) {
return obj.GetHashCode();
}
}
public static IObservable<TSource> CollectDuplicates<TSource>(this IObservable<TSource> source) {
var dubplicateCollector = new DubplicateCollector<TSource>();
var compositeDisposable = new CompositeDisposable { source.Distinct(dubplicateCollector).Subscribe() };
return Observable.Create<TSource>(observer => {
var disposable = dubplicateCollector.Matches.Subscribe(observer.OnNext, observer.OnError, observer.OnCompleted);
compositeDisposable.Add(disposable);
return () => compositeDisposable.Dispose();
});
}
}
公共类测试:ReactiveTest{
[事实]
公共无效观察\u区分\u不区分(){
var scheduler=newtestscheduler();
var source=scheduler.CreateHotObservable(
OnNext(100,“a”),
OnNext(110,“b”),
OnNext(200,“a”),
OnNext(220,“c”),
OnNext(221,“a”)
).Publish();
var distinntresults=scheduler.CreateObserver();
source.Distinct().Subscribe(distinntresults);
var duplicatesResults=scheduler.CreateObserver();
source.CollectDuplicates().Subscribe(duplicatesResults);
source.Connect();
调度程序提前(1000);
distinntresults.Messages.AssertEqual(OnNext(100,“a”)、OnNext(110,“b”)、OnNext(220,“c”);
重复结果.Messages.AssertEqual(OnNext(200,“a”)、OnNext(221,“a”);
}
}
公共静态类RxEx{
DubplicateCollector类:IEqualityComparer{
只读主题匹配=新主题();
public IObservable Matches=>\u Matches;
公共布尔等于(TX,TY){
var@equals=x.equals(y);
如果(等于)
_匹配项OnNext(x);
返回@equals;
}
公共int GetHashCode(T obj){
返回obj.GetHashCode();
}
}
公共静态IObservable CollectDuplicates(此IObservable源){
var dubplicateCollector=新的dubplicateCollector();
var compositeDisposable=new compositeDisposable{source.Distinct(dubplicateCollector.Subscribe()};
返回可观察的。创建(观察者=>{
var disposable=dubplicateCollector.Matches.Subscribe(observer.OnNext、observer.OnError、observer.OnCompleted);
可合成。添加(一次性);
return()=>compositeDisposable.Dispose();
});
}
}
你好,亚伦。你能用lambda表达式而不是查询表达式来写这个吗?我一直在苦苦挣扎:(没关系,我明白了!起初我没有意识到我会使用Buffer
,但我不是作者:)啊,哈哈!我没有意识到。作者您好:),谢谢您的回答,但是当a
存在超过2次时,解决方案就不起作用了。你能重构到一个更通用的解决方案吗更新了我的答案。