2016-05-09 2 views
2

Wie kann ich den Wert einer Eigenschaft erhalten, die ein String-Argument gegeben.Wie Wert der Eigenschaft in Abhängigkeit von einem Argument gelesen wird

Ich habe ein Objekt CsvProvider.Row, das die Attribute a, b, c hat. Ich möchte den Attributwert abhängig von der Eigenschaft als String-Argument erhalten. Ich habe versucht, so etwas wie diese:

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

aber es gibt mir die folgende Fehlermeldung:

getValue(tuple, "a") 

und es sollte gleichwertig sein:

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

Einfacher Aufruf Funktion soll wie folgt aussehen zur folgenden Funktion:

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

Ist so etwas überhaupt möglich?

Danke für jede Hilfe!

+4

Sie brauchen Reflexion dafür - aber warum verwenden Sie nicht einen Getter anstelle des Namens? 'lass getValue (ts, getter: CsvProvider <"s.csv"> .Row -> 'a) = ...' – Carsten

+0

@Carsten yup ich könnte, aber ich dachte, dass ich es so machen kann, denn für mich wird es ein ziemlich besser aussehen . Also nehme ich an, ich sollte etwas schreiben wie Sie vorschlagen oder lassen getValue (Tupel, name: string) = snd Tupel |> Seq.averageBy (fun y -> typedefof .Row> .GetField (name). GetValue():?> Float) – MNie

+0

es liegt an dir, aber die Wahl gegeben * I * würde nie magische Zeichenfolgen oder Reflexion verwenden, wenn ich Compiler überprüfen Ausdrücke haben kann – Carsten

Antwort

2

Der Provider vom CSV-Typ eignet sich hervorragend, wenn Sie statisch auf Daten mit Spaltennamen zugreifen, da Sie eine schöne automatische Vervollständigung mit Typinterferenzen und -überprüfungen erhalten.

jedoch für einen dynamischen Zugriff, könnte es einfacher sein, die zugrunde liegenden CsvFile (auch einen Teil von F # Data) direkt zu verwenden, anstatt mit dem Typ-Anbieter:

// 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)) 

Die einzige unglückliche Sache ist, dass Auf die Elemente wird per Index zugegriffen, daher müssen Sie eine Nachschlagetabelle erstellen, wenn Sie sie einfach über ihren Namen erreichen möchten.

+0

Danke für eine Antwort. Yup es scheint ein kleines Problem zu sein, dass, wenn ich CsvFile verwende, um Eigenschaften zu erhalten, ich Index verwenden muss. Ich dachte, dass CSVProvider auch direkt solche Funktionalität zur Verfügung stellt, aber es scheint nicht (oder nicht jetzt). Obwohl Ihre Antwort meine Frage "beantwortet", werde ich sie akzeptieren. Danke vielmals! – MNie

Verwandte Themen