F# F中带有元组的Group by#
假设我有一个元组列表,如下所示:F# F中带有元组的Group by#,f#,F#,假设我有一个元组列表,如下所示: [("A",12); ("A",10); ("B",1); ("C",2); ("C",1)] 我想做一些groupby我该如何处理 在伪代码SQL中,它应该如下所示: SELECT fst(tpl), sum(lst(tpl)) FROM [TupplesInList] GROUP BY fst(tpl) 屈服 [("A",22); ("B",1); ("C",3)] 如果键存在,我可以制作一个字典并添加int,但我很难相信这是像F#这样表达能力强的
[("A",12); ("A",10); ("B",1); ("C",2); ("C",1)]
我想做一些groupby
我该如何处理
在伪代码SQL中,它应该如下所示:
SELECT fst(tpl), sum(lst(tpl)) FROM [TupplesInList] GROUP BY fst(tpl)
屈服
[("A",22); ("B",1); ("C",3)]
如果键存在,我可以制作一个字典并添加int,但我很难相信这是像F#这样表达能力强的语言中的最佳解决方案。一个解决方案:
let tuples = [("A",12); ("A",10); ("B",1); ("C",2); ("C",1)]
tuples
|> Seq.groupBy fst
|> Seq.map (fun (key, values) -> (key, values |> Seq.sumBy snd))
编辑:…或不带管道:
let tuples = [("A",12); ("A",10); ("B",1); ("C",2); ("C",1)]
Seq.map (fun (key, group) -> key, Seq.sumBy snd group)
(Seq.groupBy fst tuples)
为了扩展Johan的答案,我经常做这类事情,所以做了以下的广义函数
let group_fold key value fold acc seq =
seq |> Seq.groupBy key
|> Seq.map (fun (key, seq) -> (key, seq |> Seq.map value |> Seq.fold fold acc))
这适用于您的元组大小写,如下所示
let tuples = [("A",12); ("A",10); ("B",1); ("C",2); ("C",1)]
let regular = group_fold fst snd (+) 0 tuples
let piped = tuples |> group_fold fst snd (+) 0
但也可以与其他sequence一起使用,比如字符串列表
let strings = ["A12"; "A10"; "B1"; "C2"; "C1"]
let regular = group_fold (fun (x : string) -> x.[0]) (fun (x : string) -> int x.[1..]) (+) 0 strings
let piped = strings |> group_fold (fun x -> x.[0]) (fun x -> int x.[1..]) (+) 0