我在这里阅读了很多帖子,这些帖子对我的问题很有帮助,但我的所有尝试都没有结果。
听到我的代码:
第一个功能(逐行使用的读取文件)
let readLines filePath = System.IO.File.ReadLines(filePath)
第二功能(处理线) 编辑:拼写错误我在第一篇文章中忘记了字符串行
let processLine (line:string) (myobj:MYOBJ) =
// .... some processing
myobj // I return the object modified
现在我想用这个异步处理文件(尝试不起作用!但目的是解释我希望它做什么)
let processAll file =
async { // some processing
let mutable obj = new MYOBJ()
readLines file
|> Seq.iter (fun l -> let obj = proceesLine l ) // I would like to modify the object after each Line
}
我尝试过使用ref和!处理突变,但没有提出一个干净,清晰的解决方案。 在这种情况下,最好的代码实践是什么?
可能的解决方案: 谢谢你的宝贵帮助,这里有两种可能的解决方案
第一个解决方案:
let readL (file:string) =
async {
let mutable myobj = ref(new MYOBJ())
use sr = new StreamReader(file)
while not sr.EndOfStream do
let line = sr.ReadLine()
myobj := proccesLine line !myobj
()
sr.Close()
}
第二个解决方案:(使用CSVReader库)
let readL (file:string) =
async {
let myobj = new MYOBJ()
use sr = new CsvReader(new StreamReader(file),false)
let fcount = sr.FieldCount
let data : string array = Array.zeroCreate fcount
let rec readLinloop (readNext, str:CsvReader, obj:MYOBJ) =
match readNext with
| false -> ()
| true -> sr.CopyCurrentRecordPartTo(data,0)
let obj = processLine data obj
readL(str.ReadNextRecord(), str, obj)
readLinLoop(sr.ReadNextRecord(),sr, myobj)
sr.Dispose()
}
现在,我仍然想知道是否可以使用内联函数在使用Seq.iter时返回除单元类型之外的其他内容。代码会更容易阅读。
编辑:iljarn提出的解决问题的第三个解决方案
let processAll file =
async { (MYOBJ(), readLines file) ||> Seq.fold processLine }
答案 0 :(得分:2)
这似乎是Seq.fold
的适当用例:
let processAll file =
async { (MYOBJ(), readLines file) ||> Seq.fold (fun o l -> processLine l o) }
请注意,如果您颠倒processLine
参数的顺序,那么这可以简化为:
let processAll file =
async { (MYOBJ(), readLines file) ||> Seq.fold processLine }