C#列表 - 分组依据 - 如果没有的Linq [英] C# List - Group By - Without Linq

查看:102
本文介绍了C#列表 - 分组依据 - 如果没有的Linq的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个对象:

  IObject 
{
串帐户,
十进制金额
}

我如何通过帐户组和总结的量,不返回一个列表。LINQ



2.0框架...这就是为什么没有LINQ



下面是我。

  ListofObjects =名单,LT; IObject取代; 

的foreach(对象中的无功对象)
{
变种objectToAdd =新的对象(物体);

变种OA = ListofObjects.Find(X => x.Account == objectToAdd.Account);

如果(OA == NULL)
{
ListofObjects.Add(objectToAdd);
}
,否则
{
ListofObjects.Remove(OA);
oa.Amount = objectToAdd.Amount;
ListofObjects.Add(OA);
}


}


解决方案

最简单的答案:使用 LINQBridge 并让你的所有的LINQ到对象善良对.NET 2.0 ...效果最好,如果你可以使用C#3(即VS2008,但针对.NET 2.0)。



如果你真的不能做到这一点,你基本上需要保持字典从一键的值的列表。通过序列迭代,并检查它是否已经包含了清单 - 如果不是,添加一个。然后,加入你发现任何列表(无论是新的还是旧的)。



如果您需要返回组按键的顺序,你也需要保持一个在这你发现他们的命令键列表。坦率地说这是一个痛苦......刚刚获得LINQBridge来代替:)



(严重的是,LINQ的各个位其实是相当容易写 - 但它也很容易使关闭接一个错误,或者最终会忘记在它实际上是一个的ICollection<的情况下,以优化像计数(); T> ...有没有必要在这里重新发明轮子)



编辑:我正要写一些代码,但后来我发现,你想一个列表的返回......一个什么样的名单? A 列表与LT; IList的< IObject>> ?或者,你其实是想组,总和一气呵成?如果是这样,你不想对键和量的名单?或者你打算重用你已经有了一个的的帐户同一类,但作为总?如果是后者,这里的一些示例代码:

 公共静态的IList< IObject> SumAccounts(IEnumerable的< IObject>数据)
{
名单,LT; IObject> RET =新的List< IObject>();
&字典LT;字符串,IObject>地图=新词典与LT;字符串,IObject>();

的foreach(数据VAR项)
{
IObject存在;
如果(map.TryGetValue(item.Account,从现有的)!)
{
=现有新IObject(item.Account,0M);
图[item.Account] =存在;
ret.Add(现有的);
}
existing.Amount + = item.Amount;
}
返回RET;
}



在这里,由于使用词典诚然额外的效率进行查找将是毫无意义的,除非你有真的不可小视帐户...



编辑:如果你有一个小帐户数量,按您的意见,您可以使用:

 公共静态的IList< IObject> SumAccounts(IEnumerable的< IObject>数据)
{
名单,LT; IObject> RET =新的List< IObject>();

的foreach(数据VAR项)
{
IObject现有= ret.Find(X => x.Account == item.Account);
如果(现有== NULL)
{
=现有新IObject(item.Account,0M);
ret.Add(现有的);
}
existing.Amount + = item.Amount;
}
返回RET;
}


I have an object:

IObject
{
    string Account,
    decimal Amount
}

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

2.0 Framework ... that is why no Linq.

Here is what I have:

    ListofObjects = List<IObject>;

    foreach (var object in objects)
    {
        var objectToAdd = new Object(object);

        var oa = ListofObjects.Find(x => x.Account == objectToAdd.Account);

        if (oa == null)
        {
            ListofObjects.Add(objectToAdd);
        }
        else
        {
            ListofObjects.Remove(oa);
            oa.Amount = objectToAdd.Amount;
            ListofObjects.Add(oa);
        }


    }

解决方案

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<T>... 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<IList<IObject>>? 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<IObject> SumAccounts(IEnumerable<IObject> data)
{
    List<IObject> ret = new List<IObject>();
    Dictionary<string, IObject> map = new Dictionary<string, IObject>();

    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<IObject> SumAccounts(IEnumerable<IObject> data)
{
    List<IObject> ret = new List<IObject>();

    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;
}

这篇关于C#列表 - 分组依据 - 如果没有的Linq的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆