昨日、Wes DyerがReactiveExtensions(Rx)を使用してドラッグ'n'ドロップを実装する方法を示す、最初のRxアプリケーションの作成(チャネル9)のスクリーンキャストを見ました。私がまだ理解していないこと:
スクリーンキャストの終わりに向かって、WesDyerは次のように入力します。
var q = from start in mouseDown
from delta in mouseMove.StartsWith(start).Until(mouseUp)
.Let(mm => mm.Zip(mm.Skip(1), (prev, cur) =>
new { X = cur.X - prev.X, Y = cur.Y - prev.Y }))
select delta;
簡単に言うとq
、マウスの移動座標デルタをサブスクライバーにプッシュするオブザーバブルです。
私が理解していないのは、どうすればうまくいくのかということですmm.Zip(mm.Skip(1), ...)
!?
私の知る限り、IObservable
そういう意味でIEnumerable
は列挙できません。の「プル」の性質のおかげでIEnumerable
、それは何度も何度も繰り返すことができ、常に同じアイテムを生み出します。(少なくとも、これはすべての正常に動作する列挙型に当てはまるはずIObservable
です。)動作は異なります。アイテムは一度サブスクライバーにプッシュされ、それだけです。上記の例では、マウスの動きは単一のインシデントであり、メモリに記録されていないと繰り返すことができません。
では、彼らが取り組んでいるマウスイベントは単一の再現不可能なインシデントであるため、との組み合わせはどのように機能する.Zip
可能性がありますか?この操作では、それを独立して2回「確認」.Skip(1)
する必要はありませんか?mm
参考までに、次のメソッドシグネチャを使用しObservable.Zip
ます。
public static IObservable<TResult> Zip <TLeft, TRight, TResult>
(
this IObservable<TLeft> leftSource, // = mm
IObservable<TRight> rightSource, // = mm.Skip(1)
Func<TLeft, TRight, TResult> selector
)
PS:オペレーターには、非常に洞察に満ちた別のスクリーンキャストZip
があるのを見ました。