F# Sequences - how to return multiple rows

≯℡__Kan透↙ 提交于 2019-12-24 09:28:10

问题


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 ?


回答1:


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.




回答2:


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 [| ... |])




回答3:


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)



回答4:


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.



来源:https://stackoverflow.com/questions/4989920/f-sequences-how-to-return-multiple-rows

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!