我正在嘗試創建一個使用 and 的 Rx.NET 運算子Observable<string>:
- 如果第一個元素是,則轉發每個元素不變
"a" - 否則僅發出完成信號
例如:
-a-b-c-d-|- --> -a-b-c-d-|-
-b-c-d-|- --> -|-
我怎樣才能做到這一點?
uj5u.com熱心網友回復:
這是一個絕對沒有競爭條件的版本:
public static IObservable<T> IfFirstElement<T>(this IObservable<T> source, T expectedFirstElement) =>
source
.Publish(published =>
from x in published.Take(1)
from y in
x.Equals(expectedFirstElement)
? published.StartWith(x)
: Observable.Empty<T>()
select y);
有方法語法版本:
public static IObservable<T> IfFirstElement<T>(this IObservable<T> source, T expectedFirstElement) =>
source
.Publish(published =>
published
.Take(1)
.SelectMany(x =>
x.Equals(expectedFirstElement)
? published.StartWith(x)
: Observable.Empty<T>()));
我更喜歡查詢語法,但是嘿...
uj5u.com熱心網友回復:
這是一種方法:
/// <summary>
/// If the first element has the expected value, return the whole sequence.
/// Otherwise, return an empty sequence.
/// </summary>
public static IObservable<T> IfFirstElement<T>(this IObservable<T> source,
T expectedFirstElement, IEqualityComparer<T> comparer = default)
{
comparer ??= EqualityComparer<T>.Default;
return source.Publish(published =>
published
.Where(x => !comparer.Equals(x, expectedFirstElement))
.Take(1)
.IgnoreElements()
.Amb(published)
);
}
這個實作使用了Amb運算子(“ambiguous”的縮寫),它接受兩個序列并傳播第一個反應的序列。
- 如果第一個元素具有所需的值,則第一個序列(
published.WhereTakeIgnoreElements)不會反應,因此會傳播第二個序列(published,即整個序列)。此時第一個序列已取消訂閱,因此comparer.Equals不會為后續元素呼叫該方法。 - 如果第一個元素沒有所需的值,則第一個序列發出完成通知,該通知由
Amb運算子傳播,而第二個序列(整個序列)將被忽略。
用法示例:
IObservable<string> original = new string[] { "a", "b", "c", "d" }.ToObservable();
IObservable<string> transformed = original.IfFirstElement("a");
注意:此實作基于以下假設:當兩個序列同時反應時,Amb操作員始終選擇第一個序列。檔案中沒有提到這一點,該檔案僅說明“Amb操作員使用并行處理來檢測哪個序列產生第一項”。該源代碼是相當復雜的,所以我不能閱讀它派生這個保證。如果你想要更可靠的東西,你可以試試這個實作:
return Observable.Create<T>(observer =>
{
bool first = true;
return source.Subscribe(item =>
{
if (first)
{
first = false;
if (!comparer.Equals(item, expectedFirstElement))
{
observer.OnCompleted(); return;
}
}
observer.OnNext(item);
}, observer.OnError, observer.OnCompleted);
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/347535.html
上一篇:Intellisense未顯示.Length、.Count方法
下一篇:雙擊串列框項–C#
