F#将映射输入写入输出

时间:2015-11-05 22:37:33

标签: f#

我是F#的新手,我从一个简单的项目开始。

我处理的是大型txt文件 - 通常大约有1000万条记录。我想要做的是读取文件,过滤掉一些特定的行,将字段映射到只从原始文件中获取一部分列,然后输出结果。

我有两个问题:

  1. 如何根据地图进行过滤。该文件有大约30个字段。
  2. 如何获取地图的输出并将其写入新的TXT文件
  3. 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'不匹配。

3 个答案:

答案 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