2013-06-30 14 views
10

Ich fange gerade an, mit F # zu arbeiten und versuche typische Idome und effektive Denk- und Arbeitsweisen zu verstehen.Datei transformieren in F #

Die vorliegende Aufgabe besteht aus einer einfachen Umwandlung einer durch Tabulatoren getrennten Datei in eine durch Kommas getrennte Datei. Eine typische Eingabezeile wird wie folgt aussehen:

let line = "@ES# 01/31/2006 13:31:00 1303.00 1303.00 1302.00 1302.00 2514 0" 

ich mit Looping Code wie folgt begann:

// inFile and outFile defined in preceding code not shown here 

for line in File.ReadLines(inFile) do 
    let typicalArray = line.Split '\t' 
    let transformedLine = typicalArray |> String.concat "," 
    outFile.WriteLine(transformedLine) 

I ersetzt dann das Split/concat Paar von Operationen mit einem einzigen Regex.Replace():

for line in File.ReadLines(inFile) do 
    let transformedLine = Regex.Replace(line, "\t",",") 
    outFile.WriteLine(transformedLine) 

Und jetzt haben schließlich die Schleife mit einer Pipeline ersetzt:

File.ReadLines(inFile) 
    |> Seq.map (fun x -> Regex.Replace(x, "\t", ",")) 
    |> Seq.iter (fun y -> outFile.WriteLine(y)) 

    // other housekeeping code below here not shown 

Während alle Versionen funktionieren, scheint mir die finale Version am intuitivsten zu sein. Würde ein erfahrener F # -Programmierer diese Aufgabe erfüllen?

+0

ich tun würde, genauso, wie Sie es haben –

+1

ich in der letzten Zeile des dritten Version der anonymen Funktion auslassen würde und tun nur das: '|> Seq.iter outFile.WriteLine' –

+1

Das ist ein sehr schönes [ist und, ** im Rückblick **, offensichtlich] Vereinfachung. Vielen Dank! – akucheck

Antwort

11

Ich denke, dass alle drei Versionen vollkommen in Ordnung sind, idiomatischer Code, den F # -Experten schreiben würden.

ziehe ich das Schreiben von Code mit eingebauten Sprachfunktionen (wie for Loops und if Bedingungen), wenn sie mir das Problem lösen lassen ich habe. Diese sind zwingend erforderlich, aber ich denke, sie zu verwenden, ist eine gute Idee, wenn die API zwingend erforderlichen Code (wie outFile.WriteLine) erfordert. Wie du schon erwähnt hast - du hast mit dieser Version angefangen (und ich würde dasselbe tun).

Funktionen höherer Ordnung zu verwenden ist zu nett - obwohl ich wahrscheinlich nur tun würde, wenn ich wollte, um Daten schreiben Transformation und eine neue Sequenz oder eine Liste von Linien erhalten - dies wäre praktisch, wenn Sie File.WriteAllLines verwenden anstelle von Zeilen einzeln schreiben. Obwohl, die auch durch einfaches Umwickeln Ihrer zweite Version mit Sequenz Ausdruck getan werden könnte:

let transformed = 
    seq { for line in File.ReadLines(inFile) -> Regex.Replace(line, "\t",",") } 
File.WriteAllLines(outFilePath, transformed) 

Ich glaube nicht, dass es ein objektiver Grund für eine der Versionen zu bevorzugen. Meine persönliche stilistische Präferenz besteht darin, for zu verwenden und References in Sequenzausdrücke umzuwandeln (falls erforderlich), aber andere werden wahrscheinlich nicht zustimmen.

+0

Danke, Tomas - sehr geschätzt. – akucheck