F#等价的++运算符

时间:2017-03-15 15:24:20

标签: 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 }

这很有效,但我真的不喜欢ref cell,因为它不是并发的。是否有更好/更清洁的方法来实现这一目标?

2 个答案:

答案 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"