以F#分组总计-易于使用序列,是否可以使用列表? [英] Group totals in F# - easy with sequences, is it possible with lists?

查看:53
本文介绍了以F#分组总计-易于使用序列,是否可以使用列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出一个组ID/值元组的序列,可以很容易地计算组总数(与使用C#和LINQ的方式几乎相同):

Given a sequence of a group id/value tuples, it was easy to calculate group totals (pretty much the same way I would do it with C# and LINQ):

let items = ["g1",5; "g2",10; "g1",20]

let groupsums = 
    items  
    |> Seq.groupBy (fun x -> fst x) 
    |> Seq.map (fun (g, s) -> Seq.fold (fun acc x -> acc + snd x) 0 s)

但是对于F#来说是新手,我看不出有什么方法可以使列表如此.我是否必须使用可变变量,或者有功能的方法可以对列表执行相同的操作?

But being new to F#, I can't see a way to so the same with lists. Do I have to use mutable variables, or is there a functional way to do the same with lists?

推荐答案

List.groupBy中没有内置.许多F#内置类型的函数都分配有该函数的seq版本.例如来自list.fs

There is no built in List.groupBy. A number of F# built in types have functions that are assigned the seq version of said function. e.g. from list.fs

let inline sumBy f (list : list<_>) = Seq.sumBy f list

我非常确定F#的设计人员已经进行了很多讨论,以讨论为保持一致性而复制的内容以及为进行DRY而忽略的内容.我个人希望他们坚持使用DRY.

I'm pretty sure the designers of F# had many discussions about what to duplicate for the sake of consistency and what to omit for for sake of DRY. I personally wish they stuck with DRY.

如果您要创建自己的功能性" List.groupBy,我将使用地图和列表.

If you want to make your own "functional" List.groupBy I'd use map and list.

let groupBy list =
    list 
    |> List.fold (fun group (g, x) -> 
        match group |> Map.tryFind g with
        | Some(s) -> group |> Map.remove g |> Map.add g (x::s)
        | None -> group |> Map.add g [x]
        ) Map.empty
    |> Map.toList 

let groupsums = groupBy >> List.map (snd >> List.sum)

如果只需要总和,则可以跳过保留列表.

You can skip keeping lists if you only need the sum.

let groupAndSumBy list =
    list 
    |> List.fold (fun group (g, x) -> 
        match group |> Map.tryFind g with
        | Some(s) -> group |> Map.remove g |> Map.add g (x + s)
        | None -> group |> Map.add g x
        ) Map.empty
    |> Map.toList
    |> List.map snd

输出

> groupsums items;;
val it : int list = [25; 10]

> groupAndSumBy items;;
val it : int list = [25; 10]

这篇关于以F#分组总计-易于使用序列,是否可以使用列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆