Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# F#按多个值和集合分组_C#_Linq_F#_Grouping - Fatal编程技术网

C# 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

F#。我有一个以下类型的交易列表:

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