let x = [for p in db.ParamsActXes do
if p.NumGroupPar = grp then
yield p.Num, p.Name]
这是我的序列,但问题是它返回元组列表,我无法访问单个元组元素,如
let str = "hello" + x.[1]
这就是麻烦。
我怎样才能实现这个功能呢?
答案 0 :(得分:4)
要访问2元组的第二个元素,您可以使用snd
或模式匹配。因此,如果tup
是一个2元组,tup
的第二个元素是一个字符串,您可以这样做:
let str = "hello" + snd tup
或
let (a,b) = tup
let st = "hello" + b
请注意,snd
仅适用于2元组,而不适用于包含两个以上元素的元组。
答案 1 :(得分:3)
为了给您提供另一种替代解决方案,您可以通过编写yield p
来创建包含原始类型值的过滤序列:
let x = [ for p in db.ParamsActXes do
if p.NumGroupPar = grp then
yield p ]
然后只需访问您需要的房产:
let str = "hello" + x.[1].Name
如果您只返回p
值的多个属性,这可能是一个好主意。产生元组的唯一原因是隐藏代码的其余部分或创建与稍后使用的函数匹配的序列。
(另外,我会避免使用x.[i]
索引到列表中,因为这样效率很低 - 但这可能仅适用于您发布的示例中的ilustration。如果您需要通过包装序列表达式来进行基于索引的访问,请使用数组进入[| ... |]
)
答案 2 :(得分:2)
只是为了再增加一个可能性,如果你运行的是F#2.0的.NET 4.0版本,你可以执行从F#元组到.NET 4.0 System.Tuple的运行时转换,然后使用{{1} .NET 4.0元组的属性,用于访问所需的元组元素,
ItemX
但是,我永远不会使用它,而是选择模式匹配提取。 (另外,我已经读过F#编译器可能并不总是选择将其元组表示为.NET 4.0元组的地方,因此可能存在转换失败的可能性。)
在其他一些答案中阅读您的评论,我不确定为什么模式匹配解决方案不适合您。也许您想要访问表达式中某个位置的元组项?如果是这样,之前肯定会有效:
let x = (1, 1.2, "hello")
let y = ((box x) :?> System.Tuple<int, float, string>);;
y.Item3 //returns "hello"
但你也可以使用模式匹配提取技术达到同样的目的(再次假设这甚至是你所追求的):
let str = "hello" + ((box x.[1]) :?> System.Tuple<int,string>).Item2 //though might as well use snd and fst for length 2 F# tuples
答案 3 :(得分:1)
您可以使用List.nth。
从元组列表中访问单个元组let first, second = List.nth x 0
第一个和第二个代表元组的单个元素。