F#noob-地图及;减少字数

F#noob-地图及;减少字数,f#,mapping,F#,Mapping,我正在尝试F#并尝试将一个单词列表的地图缩减为一个单词,count 这是我到目前为止得到的 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); (

我正在尝试F#并尝试将一个单词列表的地图缩减为一个单词,count

这是我到目前为止得到的

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)]
但是


现在我对如何设计一个reduce函数以使其具有单词、计数对列表感到困惑。有什么建议吗?我感谢你的帮助!谢谢

您实际上不需要
地图
列表。直接将列表放入关联映射更简单:

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)]
>减少数据量1
val it:Map=Map[(“你好”,2);(“如何”,2);(“是”,1);(“如何”,1)]

关于如何使用缩减功能
折叠
,以及如何使用关联地图数据结构
地图
,有一个很好的解释。这是一个效率相对较低但易于理解的解决方案:

data1 |> Seq.groupBy id |> Seq.map (fun (a,b) -> a,Seq.length b)
基本上,先分组,然后查看每个组中有多少个元素

@ildjarn指出了一个改进,这可能是最有效的,也更简单:

data1 |> Seq.countBy id

有一个内置的功能:

data1 |> Seq.countBy id
这将为您提供一系列元组:

val it : seq<string * int> =
    seq [("Hello", 2); ("How", 2); ("how", 1); ("are", 1)]
如果您想要
地图
,这也很简单:

> data1 |> Seq.countBy id |> Map.ofSeq;;
val it : Map<string,int> =
  map [("Hello", 2); ("How", 2); ("are", 1); ("how", 1)]
>data1 |>Seq.countBy id |>Map.of Seq;;
ValIT:地图=
地图[(“你好”,2);(“如何”,2);(“是”,1);(“如何”,1)]

为什么不
Seq.countBy id
?@ildjarn-没有想到,但它要好得多
> data1 |> Seq.countBy id |> Seq.toList;;
val it : (string * int) list =
  [("Hello", 2); ("How", 2); ("how", 1); ("are", 1)]
> data1 |> Seq.countBy id |> Map.ofSeq;;
val it : Map<string,int> =
  map [("Hello", 2); ("How", 2); ("are", 1); ("how", 1)]