简体   繁体   English

如何在F#中引用任何大小的元组的特定成员

[英]How can I refer to a specific member of a Tuple of any size in F#

okay, this might be a silly question. 好吧,这可能是一个愚蠢的问题。

So I have some tuples of size 4 so like (int,int,int,int) 所以我有一些大小为4的元组,因此(int,int,int,int)

If it were a 2 tuple I could use fst(myTuple) to refer to the first element. 如果它是2元组,我可以使用fst(myTuple)来引用第一个元素。 How could I, say, refer to the third element of a 4 tuple? 我怎么能说,参考4元组的第三个元素?

Use pattern matching: 使用模式匹配:

let tup = 1, 2, 3, 4
let _,_,third,_ = tup
printfn "%d" third // displays "3"

This is described directly in the MSDN documentation for tuples: Tuples (F#) 这在元组的MSDN文档中直接描述: 元组(F#)

Here's a version of @Daniels novel solution which calculates Rest offsets of the underlying Tuple representation to support position-based access on arbitrarily long tuples. 这是@Daniels新颖解决方案的一个版本,它计算底层元组表示的Rest偏移,以支持任意长元组的基于位置的访问。 Error handling omitted. 错误处理省略。

let (@) t idx =
    let numberOfRests = (idx - 1) / 7
    let finalIdx = idx - 7 * numberOfRests
    let finalTuple =
        let rec loop curTuple curRest =
            if curRest = numberOfRests then curTuple
            else loop (curTuple.GetType().GetProperty("Rest").GetValue(curTuple, null)) (curRest+1)
        loop t 0

    finalTuple
     .GetType()
     .GetProperty(sprintf "Item%d" finalIdx)
     .GetValue(finalTuple, null) 
     |> unbox

//fsi usage:
> let i : int = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36)@36;;

val i : int = 36

For the sheer novelty, here's an overloaded operator that works for tuples of any* size. 对于纯粹的新颖性,这里是一个重载的运算符,适用于任何*大小的元组。

let (@) t idx =
    match t.GetType().GetProperty(sprintf "Item%d" idx) with
    | null -> invalidArg "idx" "invalid index"
    | p -> p.GetValue(t, null) |> unbox

//Usage
let t = 4, 5, 6
let n1 : int = t@1 //4
let i = 2
let n2 = t@i //5

* Any, in this context, has a more limited meaning, specifically, up to 7. *在这种情况下,任何具有更有限的含义,特别是最多7个。

If you want random access to a generally sized tuple, then it is not possible. 如果你想随机访问一般大小的元组,那么这是不可能的。 For any given size, you can follow ildjarn's answer (extending it for four, five, etc.), but that it the only (functional) way. 对于任何给定的大小,您可以按照ildjarn的答案(将其扩展为四,五等),但它是唯一(功能)方式。

A possibility for tuples in general, is to convert it to a list first, as found here , but that's not too pretty as it requires reflection. 一般来说,元组的一种可能性是首先将它转换为列表,如此处所示 ,但这并不是太漂亮,因为它需要反射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM