F#:获取元组的长度

时间:2015-09-23 03:28:50

标签: f# f#-interactive

有没有办法让元组长度。 我的意思是让像a=(1,2,3)这样的东西。我必须得到3

我使用以下代码将元组转换为列表并尝试获取列表的长度,但结果为option类型,我无法使用它。

let tupleToList t = 
    if Microsoft.FSharp.Reflection.FSharpType.IsTuple(t.GetType()) 
        then Some (Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields t |> Array.toList)
        else None

3 个答案:

答案 0 :(得分:3)

如果您的意图只是为任何元组参数获取一个元组长度,并且为非元组参数获得一些可区分的其他数字(如0),则无需将tuple转换为完全列表;直接

let tupleLength t =
    if Microsoft.FSharp.Reflection.FSharpType.IsTuple(t.GetType()) 
    then (Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields t |> Array.length)
    else 0

为您提供此类签名:tupleLength: t:'a -> int

在FSI中测试:

> (1,'a',10.0) |> tupleLength;;
val it : int = 3

> ("a",["b";"c";"d"]) |> tupleLength;;
val it : int = 2

["a","b","c","d"] |> tupleLength;;
val it : int = 0

答案 1 :(得分:3)

如此处所示,tupleToList函数返回obj list option,因此您将不得不处理None案例。

非元组有多长?

为了论证,我们将该长度设为0。在这种情况下,您可以使用Option.mapOption.fold获取元组的长度(以及其他值)。例子:

> (1, "2") |> tupleToList |> Option.map List.length |> Option.fold (+) 0;;
val it : int = 2

> ("1", 2, 3.0) |> tupleToList |> Option.map List.length |> Option.fold (+) 0;;
val it : int = 3

> "Not a tuple" |> tupleToList |> Option.map List.length |> Option.fold (+) 0;;
val it : int = 0

如果愿意,可以将表达式Option.map List.length |> Option.fold (+) 0绑定到函数。

答案 2 :(得分:0)

假设它总是发送元组,我认为以下内容更简单。

let t = 1,2,3


let inline countTuples t = 
 t.GetType().GetGenericArguments().Length

countTuples t
//val it : int = 3

let a = 4

countTuples a
//val it : int = 0

let list = ["4", "5"]

countTuples list
//val it : int = 1

如果不是总是元组,并且可能有通用参数(最后一个例子),那么当然需要检查元组...