我有一个项目流,我想创建一个按属性分组的订阅,直到满足条件。
例如,假设我想按名称对EventItem
进行分组,直到观察到特定的Id
为止。这一点的关键是将事件关联起来,直到我们看到一个特定的Id
,表示不再有相关事件。然后我想对每组相关事件执行一些操作。
public class EventItem
{
public int Id { get; set }
public string Name { get; set; }
}
// Using a Subject since it seems the simplest way
Subject<EventItem> eventStream;
...
// A seperate thread pushes EventItem objects into the Subject
eventStream.OnNext(eventItem);
// Struggling here...
IDisposable subscription = eventStream.????
我尝试了几种与GroupBy
,GroupByUntil
,TakeUntil
,TakeWhile
等的组合,但我无法弄清楚如何做到这一点(我是对Rx缺乏经验)
答案 0 :(得分:2)
我知道已有一个已接受的答案,但似乎过于复杂。在@Enigmativity的评论中工作:
var subscription = eventStream
.GroupBy(x => x.Name)
.Select(o => o.TakeWhile(ei => ei.Id != 42))
.SelectMany(o => o.ToList()) //If you want y to be IList<EventItem>, use this line. If you prefer y to be IObservable<EventItem>, comment out.
.Subscribe(y => {});
答案 1 :(得分:1)
修改强>
基于@Shlomo的回答以及OP关于希望它不能完成的评论
var subscription = producer
.TakeWhile(ei => ei.Id != 42)
.GroupBy(x => x.Name)
.Select(o => o)
.SelectMany(o => o.ToList()) //If you want y to be IList<EventItem>, use this line. If you prefer y to be IObservable<EventItem>, comment out.
.Repeat()
.Subscribe();
原始答案
这有用吗?
Subject<Notification> producer = new Subject<Notification>();
//This way there's only one producer feeding the group and the duration
var connectedProducer =
producer
.Publish()
.RefCount();
connectedProducer
.GroupByUntil(
item => item.Name,
item => connectedProducer.Where(x=> x.Id == 3))
.SelectMany(result =>
{
return result.Aggregate<Notification, List<Notification>>(new List<Notification>(), (dict, item) =>
{
dict.Add(item);
return dict;
});
})
//not sure if you need this but just a way to filter out the signal
.Where(item => item.First().Id != 3)
.Subscribe(results =>
{
//This will only run after a "3" is passed in and then you get a list of everything passed in with the names
//not sure if you wanted intermediate results or for it all to just come through once the signal indicates processing
});
我的基础是我之前的答案,并稍作修改。 Rx grouped throttling