2017-03-15 24 views
4

配列をレコード型に変換しています。ような何か: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 } 

これは動作しますが、私は本当に、同時ではない何かのための参照セルを嫌い:

私が思いついたのソリューションです。これを達成するためのより良い/よりクリーンな方法がありますか?

答えて

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キーワードを使用してrefを避けることができます。

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

そして、我々はgetIndex関数内

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

をうーん、私は混乱しています。私はあなたが変更可能セルを閉じると、それがrefセルでなければならないと思いました。 – mydogisbox

+2

パターンマッチングでは上向きです。配列の長さを変更してパターンを更新しないと、修正するように警告するコンパイラ警告が表示されます。 –

+4

@mydogisbox F#4.0より、refの代わりにmutableを使うことができます(コンパイラはあなたのためにそれを理解するので、ヒープに置かれます - コード内で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

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" 
関連する問題