[英]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)
但是,我无法按两个值分组,例如Debitor
和Creditor
。 理想情况下,我希望在为Spend
属性应用聚合函数“ Sum”的同时考虑Debitor
和Creditor
。
换句话说 ,我想实现以下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.