如果我在F#中有以下枚举:
type Note =
| C = 0
| D = 2
| E = 4
| F = 5
| G = 7
| A = 9
| B = 11但是在某些时候,我需要它中项目的序号,比如Note.C = 1, Note.D = 2,等等。显然,在其他语言中,foo.ordinal()可以工作,但是在这里需要使用这样的函数:
let getNoteOrdinal = function
|Note.C -> 1
|Note.D -> 2
|Note.E -> 3
|Note.F -> 4
//etc这种功能是必要的还是有更好的东西?
发布于 2019-02-08 14:49:50
.NET中的Enum只是一个整体类型之上的一个层,在这种情况下,您的值是int。
根据医生们,您可以执行一个简单的转换来获得该值,例如:
let value = int Note.B在这种情况下,value将是11。
要找到序号,您可以使用一个内置函数,该函数为您提供一个数组,按顺序排列所有值,然后找到您要查找的值的索引。例如:
let getNoteOrdinal (note: Note) =
let values = Enum.GetValues(typeof<Note>)
Array.IndexOf(values, note) + 1
let value = getNoteOrdinal Note.E在这种情况下,value将是3。
您可以像@ReedCopsey建议的那样更进一步,并创建一个泛型函数,为任何枚举值提供序号:
let getEnumOrdinal (e: 'a when 'a : enum<'b> and 'a : equality) =
let values = Enum.GetValues(e.GetType())
Array.IndexOf(values, e) + 1发布于 2019-02-08 17:02:44
我建议在F#中不要使用枚举,除非它是与另一种.NET语言进行互操作所必需的。您可以使用区分的联合并将注释值存储在数组中(这是一个模块级别的值,在应用程序启动时计算一次)。然后您可以编写使用该数组的函数。
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示例用法:
getNoteValue C // 0
getNoteValue D // 2
getNoteOrdinal C // 1
getNoteOrdinal D // 2https://stackoverflow.com/questions/54594783
复制相似问题