我有以下简短的代码,只需计算文字:
[<EntryPoint>]
let main argv =
let text = File.ReadAllText("gettysburg.txt").ToLower()
Regex.Split(text, "\W+")
|> Seq.groupBy id
|> Seq.map (fun (k, grp) -> (k, grp |> Seq.length))
|> Seq.sortByDescending (fun (w, ln) -> (ln, w))
|> Seq.iter (fun (k, ln) -> printfn "%s\t%i" k ln)
排序函数首先按出现次数排序,然后按字母顺序排序,均为降序排序。我需要按出现次数递减,然后按字母顺序递增。
使用 OrderByDescending 和 ThenBy ,LINQ非常简单。如何在不重复使用LINQ的情况下在F#中实现相同的结果?
谢谢。
答案 0 :(得分:7)
您可以改为使用CommandManager
并使出现次数为负数:
sortBy
或者,如果遇到更复杂的情况,可以使用使用比较器函数的函数|> Seq.sortBy (fun (w, ln) -> (-ln, w))
:
sortWith
事实上,第一个解决方案是针对您的特定情况的快捷方式,因为您可以将数字设为负数,但如果您有更多字段,而不是数字,那么使用|> Seq.sortWith (fun (w1, ln1) (w2, ln2) -> compare (ln2, w1) (ln1, w2))
可以实现与Linq中的sortWith
... OrderBy
,通过排序元组并在元素下降时交换元素。
请注意,两种选择都依赖于structural comparison而不是元组。
答案 1 :(得分:4)
对降序进行排序与对负数进行升序排序相同(因为a <= b
然后是-b <= -a
)所以这应该有效:
[<EntryPoint>]
let main argv =
let text = File.ReadAllText("gettysburg.txt").ToLower()
Regex.Split(text, "\W+")
|> Seq.groupBy id
|> Seq.map (fun (k, grp) -> (k, grp |> Seq.length))
|> Seq.sortBy (fun (w, ln) -> (-ln, w))
|> Seq.iter (fun (k, ln) -> printfn "%s\t%i" k ln)