2012-08-14 33 views
2

如果我有一個無限序列,我不能使用正常的Seq.tryFind如何嘗試查找無限序列中的元素?

但是,如果序列是有序的,那意味着當我檢測到序列中沒有其他元素能夠滿足我的條件時,可以取消搜索。

有沒有一種優雅的方式來表達這樣的搜索?

如果你想只使用標準功能

回答

3

這裏是另外一個可能的解決方案。這是很類似於@desco發佈,但它利用序列的表達,而不是Seq.tryPick,它也並不需要嵌套選項類型:使用內置函數

let has element input = 
    seq { for v in input do 
      if v = element then yield Some v 
      if v > element then yield None } 
    |> Seq.head 

甚至更​​好,更簡單的解決方案。只需使用Seq.takeWhile採取只包含了比你正在尋找,然後在序列的這一部分使用Seq.tryFind一個小於或等於元素序列的開始:

let has element input = 
    input |> Seq.takeWhile (fun x -> x <= element) 
     |> Seq.tryFind (fun x -> x = element) 

或者,如果你看中了點 - 免費風格(我不這樣做,因爲它會更難讀恕我直言):

let has element = Seq.takeWhile ((>=) element) >> Seq.tryFind ((=) element) 
+0

問我最終找到第二個方法我自己的問題,但第一個是相當不錯的,以及之後。謝謝! – 2012-08-14 23:39:58

+0

'takeWhile'一次返回一個元素? – R0MANARMY 2012-08-15 01:05:46

+0

如果序列只遍歷一次,會更好嗎? 'let has element = Seq.skipWhile((>)element)>> Seq.take 1 >> Seq.tryFind((=)element)' – bytebuster 2012-08-15 01:52:01

5

- 這樣的事會工作

let evens = Seq.initInfinite ((*)2) 
let has v = 
    Seq.tryPick (fun x -> 
     if x = v then Some (Some v) 
     elif x > v then Some None 
     else None) 
    >> Option.bind id 
has 40 evens // Some 40 
has 41 evens // None 
相關問題