valores - Cómo leer un archivo en un seq de líneas en F#
leer varios valores de un archivo de texto en php (5)
En .NET 2/3 puedes hacer:
let readLines filePath = File.ReadAllLines(filePath) |> Seq.cast<string>
y en .NET 4:
let readLines filePath = File.ReadLines(filePath);;
Esta es la versión de C #:
public static IEnumerable<string> ReadLinesEnumerable(string path) {
using ( var reader = new StreamReader(path) ) {
var line = reader.ReadLine();
while ( line != null ) {
yield return line;
line = reader.ReadLine();
}
}
}
Pero la traducción directa necesita una variable mutable.
Para responder a la pregunta de si hay una función de biblioteca para encapsular este patrón, no hay una función exactamente para esto, pero hay una función que le permite generar secuencias a partir de un estado llamado Seq.unfold
. Puede usarlo para implementar la funcionalidad anterior de esta manera:
new StreamReader(filePath) |> Seq.unfold (fun sr ->
match sr.ReadLine() with
| null -> sr.Dispose(); None
| str -> Some(str, sr))
El valor sr
representa el lector de flujo y se pasa como estado. Siempre que le proporcione valores no nulos, puede devolver Some
contengan un elemento para generar y el estado (que podría cambiar si lo desea). Cuando se lee null
, lo desechamos y devolvemos None
para finalizar la secuencia. Esto no es un equivalente directo, ya que no StreamReader
adecuadamente StreamReader
cuando se lanza una excepción.
En este caso, definitivamente usaría la expresión de secuencia (que es más elegante y más legible en la mayoría de los casos), pero es útil saber que también podría escribirse usando una función de orden superior.
Si está usando .NET 4.0, puede simplemente usar File.ReadLines .
> let readLines filePath = System.IO.File.ReadLines(filePath);;
val readLines : string -> seq<string>
let lines = File.ReadLines(path)
// To check
lines |> Seq.iter(fun x -> printfn "%s" x)
let readLines (filePath:string) = seq {
use sr = new StreamReader (filePath)
while not sr.EndOfStream do
yield sr.ReadLine ()
}