Reputation: 987
I am wondering if there was an existing operator or a certain logic that would allow me to reproduce the behavior of a CombineLatest
with 2 source sequences, but with the added ability to determine which of the 2 sequences was modified last. I want to, in turn, use this distinction to change the way I operate when combining the latest result of both sequences.
I think that a good way to express what I want is by giving an example of a method signature that would implement the logic I am talking of.
public static IObservable<TResult> MyOperator<TInLeft, TInRight, TResult>(
this IObservable<TInLeft> left,
this IObservable<TInRight> right,
Func<TInLeft, TInRight, bool, TResult> selector)
{
// ...magic
}
In this case, left
and right
would be the entry sequences and the selector
func passed to the method would have its boolean parameter value set to true
to indicate that it is the left
sequence that was the source of the most recent change and false
if it was the right
sequence that changed last.
Of course, for the sake of clarity, the method could also be reformulated in the following way
public IObservable<TResult> MyOperator<TInLeft, TInRight, TResult>(
this IObservable<TInLeft> left,
this IObservable<TInRight> right,
Func<TInLeft, TInRight, TResult> whenLeft,
Func<TInLeft, TInRight, TResult> whenRight)
{
// ... more magic
}
Where, instead of using a boolean to distinguish the most recently updated sequence, each sequence would have its own contained behavior in the form of a func.
A use case for such an operator would be that I want to have a shared result that depends on some combination of the left
and right
sequence (just like CombineLatest
), but that priority is given to whichever has the newest information. I hope that my intent is clear enough to understand.
Is there an existing operator that has a similar underlying logic or that could be adapted to serve this purpose ? How could I accomplish such a behavior otherwise ? I have a vague idea of some operators that could be of use, but It seems like there could be a lot of different ways and I am just not sure of the best approach to take to achieve what I want.
Upvotes: 2
Views: 230
Reputation: 13495
You can try and use the Timestamp
operator in conjunction with CombineLatest
. Something like this:
var obs1 = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp();
var obs2 = Observable.Interval(TimeSpan.FromSeconds(2)).Timestamp();
var result = Observable.CombineLatest(obs1, obs2, (v1, v2) =>
{
if(v1.Timestamp < v2.Timestamp)
{
Console.WriteLine("v1 " + v1.Timestamp);
return v1;
}
else
{
Console.WriteLine("v2 " + v1.Timestamp);
return v2;
}
});
result.Subscribe(x => Console.WriteLine(x));
Upvotes: 2
Reputation: 117175
Here's what I would do:
var combined =
source1.Timestamp()
.CombineLatest(source2.Timestamp(), (ts1, ts2) => new { ts1, ts2 });
combined.Select(x =>
x.ts1.Timestamp < x.ts2.Timestamp
? "source1 first"
: "source2 first");
Upvotes: 3