我正在尝试使用F#并尝试将地图缩小为单词列表,计数。
这是我到目前为止所拥有的,
let data1 = ["Hello"; "Hello"; "How"; "How"; "how"; "are"]
let map = data1 |> List.map (fun x -> (x, 1))
printfn "%A" map
给出以下输出:
val map : (string * int) list =
[("Hello", 1); ("Hello", 1); ("How", 1); ("How", 1); ("how", 1); ("are", 1)]
但是
let reduce = ...???
现在我对如何设计一个reduce函数感到困惑,因为它有单词,count对列表。有什么建议?我感谢您的帮助!感谢
答案 0 :(得分:4)
有一个内置函数:
data1 |> Seq.countBy id
将为您提供一系列元组:
val it : seq<string * int> =
seq [("Hello", 2); ("How", 2); ("how", 1); ("are", 1)]
id
函数是另一个内置函数,它接受一个值并返回相同的值,所以在这种情况下,它意味着你按字符串本身计算。
如果您想要list
而不是seq
,可以使用Seq.toList
:
> data1 |> Seq.countBy id |> Seq.toList;;
val it : (string * int) list =
[("Hello", 2); ("How", 2); ("how", 1); ("are", 1)]
如果您想要map
,这也很简单:
> data1 |> Seq.countBy id |> Map.ofSeq;;
val it : Map<string,int> =
map [("Hello", 2); ("How", 2); ("are", 1); ("how", 1)]
答案 1 :(得分:1)
您实际上并不需要map
列表。将列表直接放入关联映射更简单:
let reduce x =
x |> List.fold (fun m x -> match Map.tryFind x m with
| None -> Map.add x 1 m
| Some c -> Map.add x (c+1) m)
Map.empty
让我们在翻译中尝试一下:
> reduce data1
val it : Map<string,int> = map [("Hello", 2); ("How", 2); ("are", 1); ("how", 1)]
如何使用缩减函数fold
here有一个很好的解释,并且很好地解释了如何使用关联地图数据结构Map<'Key,'T>
here。
答案 2 :(得分:1)
这是一个效率相对较低但易于理解的解决方案:
data1 |> Seq.groupBy id |> Seq.map (fun (a,b) -> a,Seq.length b)
基本上,进行分组,然后查看每组中有多少元素。
@ildjarn指出了一项改进,这可能是最有效甚至更简单的:
data1 |> Seq.countBy id