我刚刚开始使用F#并试图了解典型的idoms和有效的思考和工作方式.
手头的任务是将制表符分隔文件简单转换为以逗号分隔的文件.典型的输入行将如下所示:
let line = "@ES# 01/31/2006 13:31:00 1303.00 1303.00 1302.00 1302.00 2514 0"
Run Code Online (Sandbox Code Playgroud)
我开始使用这样的循环代码:
// 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)
Run Code Online (Sandbox Code Playgroud)
然后我用一个Regex.Replace()替换了split/concat操作对:
for line in File.ReadLines(inFile) do
let transformedLine = Regex.Replace(line, "\t",",")
outFile.WriteLine(transformedLine)
Run Code Online (Sandbox Code Playgroud)
现在,最后,用管道替换了循环:
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 …Run Code Online (Sandbox Code Playgroud) 我有一个包含两列,文本和计数的CSV文件.目标是从这里转换文件:
some text once,1
some text twice,2
some text thrice,3
Run Code Online (Sandbox Code Playgroud)
对此:
some text once,1
some text twice,1
some text twice,1
some text thrice,1
some text thrice,1
some text thrice,1
Run Code Online (Sandbox Code Playgroud)
重复每一行计数次数并将计数分布在那么多行上.
在我看来,这似乎是Seq.unfold的一个很好的候选者,在我们读取文件时生成了额外的行.我有以下生成器功能:
let expandRows (text:string, number:int32) =
if number = 0
then None
else
let element = text // "element" will be in the generated sequence
let nextState = (element, number-1) // threaded state replacing looping
Some (element, nextState)
Run Code Online (Sandbox Code Playgroud)
FSI产生以下函数签名:
val expandRows : text:string * number:int32 -> (string * (string * …Run Code Online (Sandbox Code Playgroud)