C# F#按多个值和集合分组
F#。我有一个以下类型的交易列表:C# F#按多个值和集合分组,c#,linq,f#,grouping,C#,Linq,F#,Grouping,F#。我有一个以下类型的交易列表: type Transaction(Debitor: string, Spend:float, Creditor:string) = member this.Debitor = Debitor member this.Spend = Spend member this.Creditor = Creditor 我知道如何根据一个值进行分组。例如,假设我想按属性对Debitor进行分组,很容易将该属性用作组的键: let tsGr
type Transaction(Debitor: string, Spend:float, Creditor:string) =
member this.Debitor = Debitor
member this.Spend = Spend
member this.Creditor = Creditor
我知道如何根据一个值进行分组。例如,假设我想按属性对Debitor进行分组,很容易将该属性用作组的键:
let tsGroupDebitor =
transactions
|> Seq.groupBy(fun ts -> ts.Debitor)
但是,我无法按两个值进行分组,例如借方
和贷方
。理想情况下,我希望分组考虑借方
和贷方
,同时为支出
属性应用聚合函数“Sum”
换句话说,我想实现以下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))
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)))
如果要汇总每个组的交易记录以合计支出属性,可以这样做:
let tsGroupDebitor =
transactions
|> Seq.groupBy(fun ts -> (ts.Debitor, ts.Creditor))
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)))
请注意,我如何使用模式匹配模式
((借方、贷方)、值)
,以便能够访问组键的两个部分以及每个组的交易顺序(值)我明白了。因此,最后一个管道操作符|>Seq.sumBy(fun t->t.Spend)
仅应用于值
,以便仅对支出
属性求和,而sumBy
方法用于指定一个函数,该函数不能使用求和
方法。非常有用,谢谢。sumBy
是一个有用的快捷方式。如果你愿意,你可以做values |>Seq.map(fun t->t.Spend)|>Seq.sum
。