F ++等价的++运算符
问题描述:
我将数组转换为记录类型。喜欢的东西:F ++等价的++运算符
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 }
这工作,但我真的不喜欢的东西,这是不是并发裁判细胞。有没有更好的/更清洁的方法来完成这个?
答
您可以使用模式匹配。
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关键字来避免ref,就像这样;
let mutable index = -1
let getIndex =
index <- index + 1
index
如果我们隐藏了getIndex函数内部的可变
let getIndex =
let mutable index = -1
fun() ->
index <- index + 1
index
答
你可以让指数与模式匹配处理,并添加活动模式,像这样:
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"
嗯,我很困惑。我想如果你关闭一个可变的它必须是一个参考单元格。 – mydogisbox
通过模式匹配进行上传 - 如果更改数组的长度并且不更新模式,则会收到编译器警告,提醒您修复它。 –
@mydogisbox从F#4.0开始,您可以使用mutable而不是ref(编译器会为您找到它,所以它仍然会放在堆上 - 与您在代码中使用ref相同)。请参阅https://blogs.msdn.microsoft.com/fsharpteam/2014/11/12/announcing-a-preview-of-f-4-0-and-the-visual-f-tools-in-vs-2015 /,简称使用可变值 – hlo