F# equivalent of LINQ Single

后端 未结 2 2019
一生所求
一生所求 2020-12-21 08:44

Ok, so for most LINQ operations there is a F# equivalent. (Generally in the Seq module, since Seq= IEnumerable)

I can\'t find the equiv of IEmumerable.Single

相关标签:
2条回答
  • 2020-12-21 09:17

    What about

    let Single source f =
        let worked = ref false
        let newf = fun a -> 
            match f a with
            |true -> 
                if !worked = true then failwith "not single"
                worked := true
                Some(a)
            |false -> None
        let r = source |> Seq.choose newf
        Seq.nth 0 r 
    

    Very unidiomatic but probably close to optimal

    EDIT:

    Solution with exactlyOne

    let only2 f s= (Seq.filter f s) |> exactlyOne
    
    0 讨论(0)
  • 2020-12-21 09:24

    In F# 2.0, this is a solution works without enumerating the whole sequence (close to your 2nd approach):

    module Seq =
        let exactlyOne seq =
            match seq |> Seq.truncate 2 with
            | s when Seq.length s = 1 -> s |> Seq.head |> Some
            | _ -> None
    
        let single predicate =
            Seq.filter predicate >> exactlyOne
    

    I choose to return option type since raising exception is quite unusual in F# high-order functions.

    EDIT:

    In F# 3.0, as @Oxinabox mentioned in his comment, Seq.exactlyOne exists in Seq module.

    0 讨论(0)
提交回复
热议问题