F# Sequences - how to return multiple rows
let x = [for p in 开发者_运维问答db.ParamsActXes do
if p.NumGroupPar = grp then
yield p.Num, p.Name]
Here is my sequence but the problem is it returns the list of tuples, I can't access single tuple element like
let str = "hello" + x.[1]
and that is the trouble.
how can I realize this functionary ?
To access the second element of a 2-tuple you can either use snd
or pattern matching. So if tup
is a 2-tuple, where the second element of tup
is a string, you can either do:
let str = "hello" + snd tup
or
let (a,b) = tup
let st = "hello" + b
Note that snd
only works with 2-tuples, not tuples with more than two elements.
To give you one more alternative solution, you can just create a filtered sequence containing values of the original type by writing yield p
:
let x = [ for p in db.ParamsActXes do
if p.NumGroupPar = grp then
yield p ]
And then just access the property you need:
let str = "hello" + x.[1].Name
This is probably a good idea if you're returning only several properties of the p
value. The only reason for yielding tuples would be to hide something from the rest of the code or to create sequence that matches some function you use later.
(Also, I would avoid indexing into lists using x.[i]
, because this is inefficient - but maybe this is just for ilustration in the sample you posted. Use an array if you need index based access by wrapping sequence expression into [| ... |]
)
Just to throw one more possibility out there, if you are running the .NET 4.0 build of F# 2.0 you can perform a runtime cast from the F# tuple to the .NET 4.0 System.Tuple and then use the ItemX
properties of the .NET 4.0 tuples to access the tuple element you need,
let x = (1, 1.2, "hello")
let y = ((box x) :?> System.Tuple<int, float, string>);;
y.Item3 //returns "hello"
However, I would never use that, instead opting for the pattern match extraction. (also, I've read places that the F# compiler may not always choose to represent its tuples as .NET 4.0 tuples, so there may be a possibility that the cast would fail).
Reading your comments in some of the other answers, I'm unsure why the pattern matching solution doesn't work for you. Perhaps you want to access the tuple item at a certain place within an expression? If so, the previous would certainly work:
let str = "hello" + ((box x.[1]) :?> System.Tuple<int,string>).Item2 //though might as well use snd and fst for length 2 F# tuples
but you can achieve the same ends using the pattern matching extraction technique too (again, assuming this is even what you're after):
let str = "hello" + (let (_,name) = x.[1] in name)
you can access individual tuple from the list of tuple using List.nth.
let first, second = List.nth x 0
first and second represents the individual element of the tuple.
精彩评论