C# List - Group By - Without Linq

后端 未结 2 1714
眼角桃花
眼角桃花 2020-12-22 01:30

I have an object:

IObject
{
    string Account,
    decimal Amount
}

How do I group by Account and Sum the Amount, returning a List without

2条回答
  •  忘掉有多难
    2020-12-22 01:44

    Easiest answer: use LINQBridge and get all your LINQ to Objects goodness against .NET 2.0... works best if you can use C# 3 (i.e. VS2008 but targeting .NET 2.0).

    If you really can't do that, you'll basically need to keep a dictionary from a key to a list of values. Iterate through the sequence, and check whether it already contains a list - if not, add one. Then add to whatever list you've found (whether new or old).

    If you need to return the groups in key order, you'll need to also keep a list of keys in the order in which you found them. Frankly it's a pain... just get LINQBridge instead :)

    (Seriously, each individual bit of LINQ is actually fairly easy to write - but it's also quite easy to make off-by-one errors, or end up forgetting to optimize something like Count() in the case where it's actually an ICollection... There's no need to reinvent the wheel here.)

    EDIT: I was about to write some code, but then I noticed that you want a list returned... a list of what? A List>? Or are you actually trying to group and sum in one go? If so, don't you want a list of pairs of key and amount? Or are you going to reuse the same class that you've already got for a single account, but as the aggregate? If it's the latter, here's some sample code:

    public static IList SumAccounts(IEnumerable data)
    {
        List ret = new List();
        Dictionary map = new Dictionary();
    
        foreach (var item in data)        
        {
            IObject existing;
            if (!map.TryGetValue(item.Account, out existing))
            {
                existing = new IObject(item.Account, 0m);
                map[item.Account] = existing;
                ret.Add(existing);
            }
            existing.Amount += item.Amount;
        }
        return ret;
    }
    

    Admittedly the extra efficiency here due to using a Dictionary for lookups will be pointless unless you've got really quite a lot of accounts...

    EDIT: If you've got a small number of accounts as per your comment, you could use:

    public static IList SumAccounts(IEnumerable data)
    {
        List ret = new List();
    
        foreach (var item in data)        
        {
            IObject existing = ret.Find(x => x.Account == item.Account);
            if (existing == null)
            {
                existing = new IObject(item.Account, 0m);
                ret.Add(existing);
            }
            existing.Amount += item.Amount;
        }
        return ret;
    }
    

提交回复
热议问题