Transformación de archivo en F#
(1)
Creo que las tres versiones son perfectamente correctas, un código idiomático que los expertos de F # escribirían.
Por lo general, prefiero escribir código utilizando funciones de lenguaje integradas (como bucles y condiciones) si me permiten resolver el problema que tengo. Estos son imperativos, pero creo que usarlos es una buena idea cuando la API requiere un código imperativo (como outFile.WriteLine
). Como mencionaste, comenzaste con esta versión (y yo haría lo mismo).
Usar funciones de orden superior también es bueno, aunque probablemente haría eso solo si quisiera escribir una transformación de datos y obtener una nueva secuencia o lista de líneas, esto sería útil si estuviera usando File.WriteAllLines
lugar de escribir líneas una sola. por uno. Aunque, eso también podría hacerse simplemente envolviendo su segunda versión con expresión de secuencia:
let transformed =
seq { for line in File.ReadLines(inFile) -> Regex.Replace(line, "/t",",") }
File.WriteAllLines(outFilePath, transformed)
No creo que haya ninguna razón objetiva para preferir una de las versiones. Mi preferencia estilística personal es usar for
y refactor para secuenciar expresiones (si es necesario), pero otras probablemente no estén de acuerdo.
Estoy comenzando a trabajar con F # y tratando de entender idoms típicos y formas efectivas de pensar y trabajar.
La tarea en cuestión es una transformación simple de un archivo delimitado por tabuladores a uno que está delimitado por comas. Una línea de entrada típica se verá así:
let line = "@ES# 01/31/2006 13:31:00 1303.00 1303.00 1302.00 1302.00 2514 0"
Empecé con un código de bucle como este:
// 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)
Luego reemplacé el par de operaciones split / concat con un solo Regex.Replace ():
for line in File.ReadLines(inFile) do
let transformedLine = Regex.Replace(line, "/t",",")
outFile.WriteLine(transformedLine)
Y ahora, finalmente, han reemplazado el bucle con una tubería:
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
Si bien todas las versiones funcionan, la versión final me parece la más intuitiva. ¿Es así como un programador F # más experimentado lograría esta tarea?