首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有类似于.NET的enum.ordinal()的enum.ordinal构造吗?

有类似于.NET的enum.ordinal()的enum.ordinal构造吗?
EN

Stack Overflow用户
提问于 2019-02-08 14:43:06
回答 2查看 303关注 0票数 5

如果我在F#中有以下枚举:

代码语言:javascript
复制
type Note =
    | C = 0
    | D = 2
    | E = 4
    | F = 5
    | G = 7
    | A = 9
    | B = 11

但是在某些时候,我需要它中项目的序号,比如Note.C = 1, Note.D = 2,等等。显然,在其他语言中,foo.ordinal()可以工作,但是在这里需要使用这样的函数:

代码语言:javascript
复制
let getNoteOrdinal = function
    |Note.C -> 1
    |Note.D -> 2
    |Note.E -> 3
    |Note.F -> 4
    //etc

这种功能是必要的还是有更好的东西?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-08 14:49:50

.NET中的Enum只是一个整体类型之上的一个层,在这种情况下,您的值是int

根据医生们,您可以执行一个简单的转换来获得该值,例如:

代码语言:javascript
复制
let value = int Note.B

在这种情况下,value将是11

要找到序号,您可以使用一个内置函数,该函数为您提供一个数组,按顺序排列所有值,然后找到您要查找的值的索引。例如:

代码语言:javascript
复制
let getNoteOrdinal (note: Note) =
    let values = Enum.GetValues(typeof<Note>)
    Array.IndexOf(values, note) + 1

let value = getNoteOrdinal Note.E

在这种情况下,value将是3

您可以像@ReedCopsey建议的那样更进一步,并创建一个泛型函数,为任何枚举值提供序号:

代码语言:javascript
复制
let getEnumOrdinal (e: 'a when 'a : enum<'b> and 'a : equality) =    
    let values = Enum.GetValues(e.GetType())
    Array.IndexOf(values, e) + 1
票数 4
EN

Stack Overflow用户

发布于 2019-02-08 17:02:44

我建议在F#中不要使用枚举,除非它是与另一种.NET语言进行互操作所必需的。您可以使用区分的联合并将注释值存储在数组中(这是一个模块级别的值,在应用程序启动时计算一次)。然后您可以编写使用该数组的函数。

代码语言:javascript
复制
type Note = C | D | E | F | G | A | B

let noteValues =
    [| C, 0
       D, 2
       E, 4
       F, 5
       G, 7
       A, 9
       B, 11 |]

let getNoteValue note =
    noteValues |> Array.find (fun (n, _) -> note = n) |> snd

let getNoteOrdinal note =
    noteValues |> Array.findIndex (fun (n, _) -> n = note) |> (+) 1

示例用法:

代码语言:javascript
复制
getNoteValue C // 0
getNoteValue D // 2

getNoteOrdinal C // 1
getNoteOrdinal D // 2
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54594783

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档