LINQ - GroupBy并巩固

时间:2013-09-09 13:08:04

标签: linq

鉴于

class Row
{
   public int CustomerId;
   public decimal Purchase;
}

最简单的方法是获得客户总购买量的另一个系列。基本上是GroupBy加上购买的商品。

rows.GroupBy(r => r.CustomerId);

性能不是一个因素,因为集合相当小。

修改 假设Row类有几个属性,我希望分组结果是特定类型,而不是匿名。

class Row
{
   public int CustomerId;
   public decimal Purchase;
   public string SomeProp1;
   public double SomeProp2;
   public long SomeProp3;
}

class TotalsRow
{
   public int CustomerId;
   public decimal TotalPurchases;
   public string SomeProp1;
   public double SomeProp2;
   public long SomeProp3;
}

EDIT2 刚刚意识到之前的编辑没有任何意义,因为我正在整合几行。我实际上要寻找的是包含与组内所有行相等的属性。假设除了购买之外的所有上述属性都满足此要求,这就是我提出的解决方案。

rows.GroupBy(r => r.CustomerId)
    .Select(g => new TotalsRow()
                {
                    CustomerId= g.Key, 
                    TotalPurchases = g.Sum(gr => gr.Purchase),
                    SomeProp1 = g.First().SomeProp1);
                    SomeProp2 = g.First().SomeProp2);
                    SomeProp3 = g.First().SomeProp3);
                }
       );

2 个答案:

答案 0 :(得分:2)

你很亲密。 GroupBy返回一个带有Key属性的集合,以及一个循环遍历该组中项目的枚举器:

rows.GroupBy(r => r.CustomerId)
    .Select(g => new {
                    Customer = g.Key, 
                    TotalPurchases = g.Sum(gr => gr.Purchase)
                    }
           );

答案 1 :(得分:2)

rows.GroupBy(
    r => r.CustomerId,
    r => r.Purchase,
    (id, group) => new
        {
            CustomerId = id,
            SumPurchase = group.Sum()
        }
)

<强>更新
当然,假设SomeProp1-3对于具有相同CustomerId的所有行都是相同的。

第一个变体(行 - &gt;行)

rows.GroupBy(
    r => r.CustomerId,
    r => r,
    (id, group) => group.Aggregate((result, row) =>
        { result.Purchase += row.Purchase; return result; })
)

第二个变体(Row - &gt; TotalsRow)

rows.GroupBy(
    r => r.CustomerId,
    r => r,
    (id, group) =>
    {
        var first = group.First();
        return new TotalsRow
        {
            CustomerId = id,
            TotalPurchases = group.Sum(r => r.Purchase),
            SomeProp1 = first.SomeProp1,
            SomeProp2 = first.SomeProp2,
            SomeProp3 = first.SomeProp3
        };
    }
)