2
votes

Probably a very simple question - if I have a sequence of objects, on which I run Seq.find() to return a single element, how do I then access one property without storing the whole element as a variable?

e.g.

type MyType = { Id : int; Text : string }
let obs = [| { Id = 1; Text = "Hello" }; { Id = 2; Text = "Goodbye" } |] :> seq<MyType>

let getFirstText (array : seq<MyType>) = 
  array |> Seq.find(fun mt -> mt.Id = 1) |> .Text
                                            ^^^^^  
getFirstText obs |> printfn "%s" 

This gives Unexpected symbol '.' in expression.

Trying Seq.find(fun mt -> mt.Id = 1).Text gives a Type constraint mismatch - The type ''a -> MyType' is not compatible with the type 'MyType' on line 6.

You can't use Seq.Map() as the object being passed is no longer a sequence.

1

1 Answers

6
votes

Either you can use parens:

(array |> Seq.find(fun mt -> mt.Id = 1)).Text

or lambda abstraction:

array |> Seq.find(fun mt -> mt.Id = 1) |> (fun mt -> mt.Text)

Another way would be to use pick function and then you define mt symbol once:

array |> Seq.pick (fun mt -> if mt.Id = 1 then Some my.Text else None)