2010-10-02 29 views
3

有沒有辦法從F#中的序列創建觀察值?F#中序列的可觀察數

需要的行爲是訂閱生成的observable的觀察者一次接收一個序列的所有值。

編輯:該問題可以被構造爲:是否存在一個等效於Rx.Observable.FromArray([1,2,3]),如F#中的here

編輯2:謝謝大家。我花了一些時間才找到答案,只是發現desco已經回答了。爲了完整起見,這裏是它是如何工作的:

//Using the Reactive Framework. 
//References to System.CoreEx.dll and System.Reactive.dll are needed. 

open System.Linq 

let observable = Observable.ToObservable [1..10] 
let odds = observable |> Observable.filter (fun i -> i%2=1) 
let disp = odds.Subscribe (fun i -> printfn "%d" i) 
disp.Dispose() 
+0

我不知道你這個要求的行爲。你的意思是一系列可觀察的事物合併爲一個? 'fold'over'merge'也許;) – Dario 2010-10-02 10:23:40

+0

@Dario:我的意思是我需要訂閱序列的能力。例如,我會列出一個列表並將其轉換爲一個可觀察的事件,觸發連續事件,每個事件都攜帶一個列表成員。 – 2010-10-02 11:14:45

回答

10

爲防萬一你想避免額外的依賴,實際上很容易實現使用F#事件和我已經在another answer here at StackOverflow中使用的Observable.guard函數。

下面是實現連同一個簡單的例子:

module Observable = 
    let ofSeq s = 
    let evt = new Event<_>() 
    evt.Publish |> Observable.guard (fun o -> 
     for n in s do evt.Trigger(n)) 

[ 1 .. 10 ] |> Observable.ofSeq 
      |> Observable.filter (fun n -> n%2 = 0) 
      |> Observable.add (printfn "%d") 

而對於完整性,Observable.guard實施看起來是這樣的:

/// Creates an observable that calls the specified function after someone 
/// subscribes to it (useful for waiting using 'let!' when we need to start 
/// operation after 'let!' attaches handler) 
let guard f (e:IObservable<'Args>) = 
    { new IObservable<'Args> with 
     member x.Subscribe(observer) = 
     let rm = e.Subscribe(observer) in f(); rm } 
+0

非常感謝。我其實希望有這樣的事情。 – 2010-10-02 17:50:28