首页 > 解决方案 > aggregate three same lists based on two columns and sum the third column

问题描述

I have three lists of class type AggClass. I just need to aggregate these three lists.

public class AggClass
{
    private string _fan;
    private string _prefix;
    private decimal _amount;

    #region Properties

    public string Fan
    {
        get { return _fan; }
        set { _fan = value; }
    }

    public string Prefix
    {
        get { return _prefix; }
        set { _prefix = value; }
    }

    public decimal Amount
    {
        get { return _amount; }
        set { _amount = value; }
    }
    #endregion
}

If Fan and Prefix columns having same value then I just need make them as one column and Sum the Amount. How to do it?

LIST 1
FAN PREFIX   AMOUNT
F1    P1       10
F1    P2       20
F2    P2       50

LIST 2
FAN PREFIX   AMOUNT
F1    P1       30
F1    P3       20
F2    P2       30

LIST 3
FAN PREFIX   AMOUNT
F1    P1       10
F1    P3       10
F2    P2       30

OUTPUT
FAN   PREFIX   AMOUNT
F1      P1       50
F1      P2       20
F1      P3       30
F2      P2      110

I have to get output like this. How can I concat three lists same time? Is there any best way?

标签: c#

解决方案


You can use Linq: Concat (we concat all three lists into one) and then GroupBy (to combime all items by Fan and Prefix):

  using System.Linq;

  ...

  List<AggClass> list1 = ...
  List<AggClass> list2 = ...
  List<AggClass> list3 = ...

  ...

  var result = list1
    .Concat(list2)
    .Concat(list3)
    .GroupBy(item => new {Fan = item.Fan, Prefix = item.Prefix})
    .Select(group => new AggClass() {
       Fan    = group.Key.Fan,
       Prefix = group.Key.Prefix,
       Amount = group.Sum(rec => rec.Amount)       
     })
    .ToList(); // let's have a list as final result  

If group.Sum(rec => rec.Amount) doesn't compile (I have .Net 5 where Sum accepts decimal), put group.Aggregate(0m, (s, a) => s + a.Amount) to sum decimal

Edit: Same idea for different columns (see comments below):

var result = eimsRecs
   .Concat(aaRecs)
   .Concat(mtrRecs)
   .GroupBy(f => new { f.FAN, f.Prefix })
   .Select(g => new Unbilled() { 
      Pid            = g.First().Pid, 
      AgrmntId       = g.First().AgrmntId,
      UnbilledAmount = g.Sum(rec => rec.UnbilledAmount),
      ...
    })
   .ToList();

推荐阅读