F # Equivalent to ++ operator

I am converting an array to a record type. Sort of:

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

This works, but it has the disadvantage that adding a value to the middle of the array leads to manual editing of all the links to the index after this, something like this:

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

Moreover, its easy to accidentally get indexes.

The solution I came across is:

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 }

This works, but I really don't like the ref cell for something that is not parallel. Is there a better / cleaner way to do this?

+4
source share
2 answers

You can use pattern matching.

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"

When you add another entry to the array, you will edit it by editing the first match before [|one; six; two; three; four; five|].

, , , , ref, mutable, :

let mutable index = -1
let getIndex =
    index <- index + 1
    index

mutable getIndex

let getIndex =
    let mutable index = -1
    fun () ->
        index <- index + 1
        index
+5

, :

  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"
+3

Source: https://habr.com/ru/post/1672376/


All Articles