我将数组转换为记录类型。类似的东西:
let value = [|"1";"2";"3";"Not a number";"5"|]
type ValueRecord = {
One: int32
Two: int32
Three: int32
Four: string
Five: int32 }
let convertArrayToRecord (x: string array) =
{ One = x.[0] |> Int.Parse
Two = x.[1] |> Int.Parse
Three = x.[2] |> Int.Parse
Four = x.[3]
Five = x.[4] |> Int.Parse }
let recordValue = convertArrayToRecord value
这样可行,但缺点是在数组中间添加一个值会导致手动编辑所有索引引用,如下所示:
let value = [|"1";"Not a number - 6";"2";"3";"Not a number";"5"|]
type ValueRecord = {
One: int32
Six: string
Two: int32
Three: int32
Four: string
Five: int32 }
let convertArrayToRecord (x: string array) =
{ One = x.[0] |> Int.Parse
Six = x.[1]
Two = x.[2] |> Int.Parse //<--updated index
Three = x.[3] |> Int.Parse //<--updated index
Four = x.[4] //<--updated index
Five = x.[5] |> Int.Parse } //<--updated index
let recordValue = convertArrayToRecord value
此外,它很容易意外地使索引错误。
我想出的解决方案是:
let convertArrayToRecord (x: string array) =
let index = ref 0
let getIndex () =
let result = !index
index := result + 1
result
{ One = x.[getIndex ()] |> Int.Parse
Six = x.[getIndex ()]
Two = x.[getIndex ()] |> Int.Parse
Three = x.[getIndex ()] |> Int.Parse
Four = x.[getIndex ()]
Five = x.[getIndex ()] |> Int.Parse }
这很有效,但我真的不喜欢ref cell,因为它不是并发的。是否有更好/更清洁的方法来实现这一目标?
答案 0 :(得分:5)
您可以使用模式匹配。
let convertArrayToRecord = function
| [|one; two; three; four; five|] ->
{
One = int one
Two = int two
Three = int three
Four = four
Five = int five
}
| _ ->
failwith "How do you want to deal with arrays of a different length"
向阵列添加其他条目时,您可以通过将第一个匹配项编辑为[|one; six; two; three; four; five|]
来调整它。
顺便说一下,对于像你当前例子中使用的索引一样的可变索引,你可以通过使用mutable关键字来避免引用,就像这样;
let mutable index = -1
let getIndex =
index <- index + 1
index
如果我们在getIndex函数中隐藏mutable
let getIndex =
let mutable index = -1
fun () ->
index <- index + 1
index
答案 1 :(得分:3)
您可以使用模式匹配处理索引,并添加活动模式,如下所示:
let (|PInt32|_|) (s:string) =
let ok, i = Int32.TryParse(s)
if ok then Some(PInt32(s)) else None
let foo() =
match [|"1"; "2"; "Some str"|] with
| [|PInt32(x); PInt32(y); mystr|] ->
printfn "Yup"
| _ -> printfn "Nope"