繁体   English   中英

F#按一个以上值分组并进行汇总

[英]F# group by more than one value and aggregate

F#。 我有以下类型的清单transactions

type Transaction(Debitor: string, Spend:float, Creditor:string)  = 
     member this.Debitor = Debitor
     member this.Spend = Spend
     member this.Creditor = Creditor

我知道如何按一个值分组。 举例来说,我想按属性Debitor ,可以轻松地将该属性用作该组的Key:

let tsGroupDebitor =
    transactions        
    |> Seq.groupBy(fun ts -> ts.Debitor)

但是,我无法按两个值分组,例如DebitorCreditor 理想情况下,我希望在为Spend属性应用聚合函数“ Sum”的同时考虑DebitorCreditor

换句话说 ,我想实现以下LINQ查询的F#等效项:

 var transactions_GroupSameDebitorCreditor = 
     transactions
     .GroupBy(ts => new { ts.Debitor, ts.Creditor }) // group by multiple values
     .Select(gr => new 
            {
                Debitor = gr.Key.Debitor,
                Debit = gr.Sum(trans => trans.Spend), //sum the trans values per grouped relationships
                Creditor = gr.Key.Creditor
            });

返回匿名类型的IEnumerable的位置。

您可以使用元组作为组键,如下所示:

let tsGroupDebitor =
    transactions        
    |> Seq.groupBy(fun ts -> (ts.Debitor, ts.Creditor))

如果要汇总每个组的事务以汇总Spend属性,可以执行以下操作:

let tsGroupDebitor =
        transactions        
        |> Seq.groupBy(fun ts -> (ts.Debitor, ts.Creditor))
        |> Seq.map(fun ((debitor, creditor), values) -> ( debitor, creditor, values |> Seq.sumBy (fun t -> t.Spend)))

请注意,我如何将模式匹配与模式((debitor, creditor), values) ,以便能够访问组密钥的两个部分以及每个组( values )的交易顺序

let sumTransactions (transactions: Transaction list) =
    transactions
    |> Seq.groupBy(fun ts -> (ts.Creditor, ts.Debitor))
    |> Seq.map (fun ((cred, deb), ts) -> 
                    let s = ts |> Seq.sumBy (fun t -> t.Spend)
                    Transaction(deb, s , cred))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM