我正在尝试构建一个包含多个文件内容的单个序列,以便对其进行排序然后传递给图形组件。但是我一直试图将每个文件的内容折叠在一起。下面的伪代码不会编译,但希望能显示我想要实现的目的。
任何帮助,非常感谢。
open System.IO
let FileEnumerator filename = seq {
use sr = System.IO.File.OpenText(filename)
while not sr.EndOfStream do
let line = sr.ReadLine()
yield line
}
let files = Directory.EnumerateFiles(@"D:\test_Data\","*.csv",SearchOption.AllDirectories)
let res =
files
|> Seq.fold(fun x item ->
let lines = FileEnumerator(item)
let sq = Seq.concat x ; lines
sq
) seq<string>
printfn "%A" res
答案 0 :(得分:12)
您实际上是在尝试重新实现Files.Readlines,它将文件内容返回为seq<string>
。然后可以将其与Seq.concat连接:
let res = Directory.EnumerateFiles(@"D:\test_Data","*.csv",SearchOption.AllDirectories)
|> Seq.map File.ReadLines
|> Seq.concat
答案 1 :(得分:4)
要解决原始方法中的问题,您需要使用Seq.append
代替Seq.concat
。 fold
的初始值应为空序列,可以写为Seq.empty
:
let res =
files |> Seq.fold(fun x item ->
let lines = FileEnumerator(item)
let sq = Seq.append x lines
sq ) Seq.empty
如果您想使用Seq.concat
,则必须编写Seq.concat [x; lines]
,因为concat
需要连接一系列序列。另一方面,append
只需要两个序列,因此在这里使用起来更容易。
连接所有行的另一种(更简单的)方法是在序列表达式中使用yield!
:
let res =
seq { for item in files do
yield! FileEnumerator(item) }
这将通过迭代所有文件并将文件中的所有行(按顺序)添加到结果序列来创建序列。 yield!
构造将序列的所有元素添加到结果中。