F#noob - map&减少言语

时间:2014-03-15 04:31:16

标签: f# mapping

我正在尝试使用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对列表。有什么建议?我感谢您的帮助!感谢

3 个答案:

答案 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