我是F#的新手,我从一个简单的项目开始。
我处理的是大型txt文件 - 通常大约有1000万条记录。我想要做的是读取文件,过滤掉一些特定的行,将字段映射到只从原始文件中获取一部分列,然后输出结果。
我有两个问题:
def x1 = [['name':'a'],['name':'b'],['name':'c']]
def x2 = x1.groupBy{it.name}
x2.containsKey('b')
我在这一行得到以下错误 - 我知道out1和out2是不同的。我该如何解决这个差异?
错误讯息:
可能的重载:
//Open the file let lines = seq {use r = new StreamReader(kDir + kfName ) while not r.EndOfStream do yield r.ReadLine() } //Filter the file let sFilt = "Detached Houses,Upper Middle" let out1 = lines |> Seq.filter (fun x -> x.Contains(sFilt)) //Write out the filtered file - this works great //val out1 : seq<string> File.WriteAllLines("c:\\temp\\out1.txt", out1 ) //Here is where I have an issue //I am trying to just get 2 of the columns to an output file //val out2 : seq<string * string> - this has a different patter than out1 let out2 = out1 |> Seq.map (fun x2 -> x2.Split[|','|]) |> Seq.map (fun x3 -> x3.[0], x3.[3])
。类型约束不匹配。类型'File.WriteAllLines(path: string, contents: IEnumerable<string>) : unit'
与类型seq<string * string>
不兼容 类型IEnumerable<string>
与类型'string'
不匹配。
答案 0 :(得分:2)
您可以做的是从seq<string>
映射回seq<string*string>
。
Seq.map (fun (str1, str2) -> sprintf "%s, %s" str1 str2)
您可以将其添加到现有的地图操作链
let out2 =
out1
|> Seq.map (fun x2 -> x2.Split[|','|])
|> Seq.map (fun x3 -> x3.[0], x3.[3])
|> Seq.map (fun (str1, str2) -> sprintf "%s, %s" str1 str2)
然后,再次,您有一系列字符串可以写入文件。
答案 1 :(得分:2)
fun x3 -> x3.[0], x3.[3]
创建一个字符串string * string
元组。你需要连接它们,例如fun x3 -> sprintf "%s,%s" x3.[0] x3.[3]
(如果您想要输出中的逗号)或fun x3 -> x3.[0] + x3.[3]
。
答案 2 :(得分:2)
如果文件结构合理,也可能要使用CsvProvider。如果文件结构合理,没有理由处理任何IO。
然后你会获得打印数据,列名等“免费”......
如果结构不完整,您可能也会使用CsvParser来严格阅读/处理文件。
看看: https://fsharp.github.io/FSharp.Data/library/CsvProvider.html 要么 https://fsharp.github.io/FSharp.Data/library/CsvFile.html