这是我第一次在这里写。 我是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();
答案 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