C#列表 – 分组 – 没有Linq

我有一个对象:

IObject { string Account, decimal Amount } 

如何按帐户分组并汇总金额,返回没有Linq的列表。

2.0框架……这就是为什么没有Linq。

这是我有的:

  ListofObjects = List; 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); } } 

最简单的答案:使用LINQBridge并获得针对.NET 2.0的所有LINQ to Objects优点…如果您可以使用C#3(即VS2008但针对.NET 2.0),效果最佳。

如果你真的不能这样做,你基本上需要保持一个字典从一个键到一个值列表。 遍历序列,检查它是否已包含列表 – 如果没有,则添加一个。 然后添加到您找到的任何列表(无论是新的还是旧的)。

如果您需要按键顺序返回组,则还需要按照找到它们的顺序保留键列表。 坦率地说,这是一个痛苦…只是得到LINQBridge 🙂

(说真的,LINQ的每个位实际上都很容易编写 – 但是它也很容易造成一个一个错误,或者在它实际上是ICollection的情况下最终忘记优化像Count()这样的东西ICollection ……这里没有必要重新发明轮子。)

编辑:我正要编写一些代码,但后来我注意到你想要一个列表返回…列表是什么? List> ? 或者你真的想一次性分组和总结? 如果是这样,你不想要一对密钥和金额对的列表吗? 或者你要重复使用你已经为一个帐户获得的同一个类,但作为聚合? 如果是后者,这里是一些示例代码:

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

不可否认,由于使用Dictionary进行查找,这里的额外效率将毫无意义,除非你有相当多的帐户…

编辑:如果你的评论中有少量帐户,你可以使用:

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

使用字典来保存结果。 在字典中定位项目接近于O(1)操作,因此它比搜索列表中的项目快得多。

 Dictionary sum = new Dictionary(); foreach (IObject obj in objects) { if (sum.ContainsKey(obj.Account)) { sum[obj.Account].Amount += obj.Amount; } else { sum.Add(obj.Account, obj.Amount); } }