如果我有一個無限序列,我不能使用正常的Seq.tryFind
。如何嘗試查找無限序列中的元素?
但是,如果序列是有序的,那意味着當我檢測到序列中沒有其他元素能夠滿足我的條件時,可以取消搜索。
有沒有一種優雅的方式來表達這樣的搜索?
如果你想只使用標準功能如果我有一個無限序列,我不能使用正常的Seq.tryFind
。如何嘗試查找無限序列中的元素?
但是,如果序列是有序的,那意味着當我檢測到序列中沒有其他元素能夠滿足我的條件時,可以取消搜索。
有沒有一種優雅的方式來表達這樣的搜索?
如果你想只使用標準功能這裏是另外一個可能的解決方案。這是很類似於@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)
- 這樣的事會工作
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
問我最終找到第二個方法我自己的問題,但第一個是相當不錯的,以及之後。謝謝! – 2012-08-14 23:39:58
'takeWhile'一次返回一個元素? – R0MANARMY 2012-08-15 01:05:46
如果序列只遍歷一次,會更好嗎? 'let has element = Seq.skipWhile((>)element)>> Seq.take 1 >> Seq.tryFind((=)element)' – bytebuster 2012-08-15 01:52:01