2016-05-09 10 views
2

文字列引数を指定してプロパティの値を取得する方法を教えてください。引数に応じてプロパティ値を読み取る方法

私は属性がa、b、cであるオブジェクトCsvProvider.Rowを持っています。 文字列引数として指定されたプロパティに応じて、属性値を取得します。 私はこのような何か試してみました:

let getValue (tuple, name: string) = 
    snd tuple |> Seq.averageBy (fun (y: CsvProvider<"s.csv">.Row) -> y.```name```) 

をしかし、それは私に次のエラーを与える:機能の

Unexpected reserved keyword in lambda expression. Expected incomplete structured construct at or before this point or other token.

単純な呼び出しは次のようになります。

getValue(tuple, "a") 

、それが同等でなければなりません

let getValue (tuple) = 
     snd tuple |> Seq.averageBy (fun (y: CsvProvider<"s.csv">.Row) -> y.a) 

このようなものも可能ですか?

ありがとうございました!

+4

あなたはこれを反映する必要がありますが、なぜ名前の代わりにゲッターを使用しないのですか? 'let getValue(ts、getter:CsvProvider <"s.csv"> .Row - > 'a)= ...' – Carsten

+0

@Carsten yup私はこれを行うことができると思っていた。 。 は、だから私はあなたが提案しているように、私が何かを書く必要があると仮定したり てみましょうのgetValue(タプル、名:文字列)= SNDタプル|> Seq.averageBy(楽しいY - > typedefof .Row> .GetField(名)。 GetValue():?> float) – MNie

+0

それはあなた次第ですが、選択肢を与えられます*私はコンパイラでチェックされた式を持つことができるとき、私は決して魔法の文字列やリフレクションを使用しません – Carsten

答えて

2

CSV型のプロバイダは、型推論とチェックで素敵な自動補完を得るため、静的に列名でデータにアクセスする場合に最適です。

しかし、ダイナミックアクセスのために、むしろタイププロバイダを使用するよりも、直接基礎となるCsvFile(F#データの一部でもある)を使用する方が簡単かもしれません:

// Read the given file 
let file = CsvFile.Load("c:/test.csv") 

// Look at the parsed headers and find the index of column "A" 
let aIdx = file.Headers.Value |> Seq.findIndex (fun k -> k = "A") 

// Iterate over rows and print A values 
for r in file.Rows do 
    printfn "%A" (r.Item(aIdx)) 

だけ不幸な事はということですアイテムはインデックスでアクセスされるため、名前で簡単にアクセスするにはルックアップテーブルを作成する必要があります。

+0

答えをありがとう。うん、それは私がCSVProviderも直接そのような機能を提供すると思っていたが、私はインデックスを使用する必要があるプロパティを取得するためにCsvFileを使用する場合、少し問題があるようだが、それは(または今はそうではないようだ)。あなたの答えは私の質問に「答えます」が、私はそれを受け入れます。どうもありがとう! – MNie

関連する問題