如何尝试在无限有序序列中查找元素?

时间:2012-08-14 22:46:08

标签: f# sequence

如果我有无限序列,我就不能使用普通Seq.tryFind

但是,如果序列是有序的,那意味着当我检测到序列中没有其他元素可以满足我的条件时,可以取消搜索。

有没有一种优雅的方式来表达这样的搜索?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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)
相关问题