创建文件后如何写文本文件

时间:2018-12-17 19:19:27

标签: file text f#

这是我第一次在这里写。 我是f#的新手,并希望获得一些帮助。 我制作了一个程序,该程序应该从现有文本文件中取出单词,对其进行编辑,然后将其写入新的文本文件中,以便按频率最高的单词排列到最少。 我已经尽力了,但是当文本文件出现时,里面却写着:

System.Tuple`2 [System.String,System.Int32] []

这是我的代码:

let reg = RegularExpressions.Regex "\s+" 
let cleanEx = RegularExpressions.Regex "[\,\.\!\"\:\;\?\-]" 
let read = (File.OpenText "clep.txt").ReadToEnd() 
let clen = (cleanEx.Replace(read, "")).ToLower() 

let clean = reg.Split(clen)
let finAr = Array.countBy id clean
let finlist = Array.sortByDescending (fun (_, count) -> count) finAr
// printfn "%A" finlist


let string = finlist.ToString()
let writer = File.AppendText("descend.txt")
writer.WriteLine(finlist);
writer.Close();

2 个答案:

答案 0 :(得分:2)

您仅向文件中写入一行文本,并且由于finlist不是StreamWriter.WriteLine()具有特定重载的类型,因此将其视为object,而使用的字符串是finlist.ToString()的结果,与内置的.NET类型一样,它只是类型名称。

如果要将数组的实际元素写入文件,则需要实际处理数组。

这会将所有元组的字符串部分写入文本文件:

finlist
|> Array.map fst
|> Array.iter writer.WriteLine

要包含数字(例如,以“文本:1”格式),则必须首先为每个数组项创建一个格式正确的字符串:

finlist
|> Array.map (fun (text, number) -> sprintf "%s: %i" text number)
|> Array.iter writer.WriteLine

顺便说一句,由于.NET字符串使用\来转义字符,就像正则表达式一样,您的RegExes不能像编写它们那样工作。应该是

let reg = RegularExpressions.Regex @"\s+"
let cleanEx = RegularExpressions.Regex @"[\,\.\!\""\:\;\?\-]"

此处有两个更改:字符串之前的@告诉编译器不要使用\来转义字符(或者,您可以在RegEx中将每个反斜杠写为\\,但这并没有使其更具可读性)。在第二个中间,另一个"转义了双引号,因为否则它们现在将终止字符串,并且该行将不再编译。

答案 1 :(得分:2)

为什么看到?

  

System.Tuple`2 [System.String,System.Int32] []

因为finAr是元组(string*int)的数组,而finlist是相同项的数组,但按计数排序。当您执行finlist.ToString()时,它不会为您提供数组项的字符串表示形式。默认情况下,ToString()(如果未覆盖)返回对象类型的全名。您所用的是元组数组。

现在您需要按频率顺序写一个单词文件了吗?只需将数组项映射到字符串:

let lines =
   clean
   |> Array.countBy id // finAr
   |> Array.sortByDescending (fun (_,count) -> count) // finlist
   |> Array.map (fun (word, _) -> word) // here mapping each tuple to string

File.WriteAllLines("descent.txt", lines)

使用几个包装器,您可以通过管道传输与读取文件和写入文件有关的操作:

"clep.txt"
|> readTextFile
|> getWordsMostFrequestFirst
|> writeLinesToFile "descent.txt"

包装:

let readTextFile (path: string) =
    (File.OpenText path).ReadToEnd()

let writeLinesToFile (path: string) (contents: string seq) =
    File.WriteAllLines(path, contents)

还有一个处理文本的函数:

let getWordsMostFrequestFirst (text: string) =
    let splitByWhitespaces (input: string) = Regex.Split(input, "\s+")
    let toLower (input: string) = input.ToLower()
    let removeDelimiters (input: string) = Regex.Replace(input, "[\,\.\!\"\:\;\?\-]", "")

    text
    |> removeDelimiters
    |> toLower
    |> splitByWhitespaces
    |> Array.countBy id
    |> Array.sortByDescending snd // easy way to get tuple items
    |> Array.map fst