我有一个对象:
IObject
{
string Account,
decimal Amount
}
Run Code Online (Sandbox Code Playgroud)
如何按帐户分组并汇总金额,返回没有Linq的列表.
2.0框架......这就是为什么没有Linq.
这是我有的:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 15
最简单的答案:使用LINQBridge并获得针对.NET 2.0的所有LINQ to Objects优点...如果您可以使用C#3(即VS2008但针对.NET 2.0),效果最佳.
如果你真的不能这样做,你基本上需要保持一个字典从一个键到一个值列表.遍历序列,检查它是否已包含列表 - 如果没有,则添加一个.然后添加到您找到的任何列表(无论是新的还是旧的).
如果您需要按键顺序返回组,则还需要按照找到它们的顺序保留键列表.坦率地说,这是一个痛苦...只是得到LINQBridge :)
(说真的,LINQ的每一个单元实际上都很容易编写 - 但它也很容易做出一个一个错误,或者最终忘记优化的东西,比如Count()它实际上是ICollection<T>......没有必要在这里重新发明轮子.)
编辑:我正要写一些代码,但后来我注意到你想要一个列表返回...列表是什么?一个List<IList<IObject>>?或者你真的想一次性分组和总结?如果是这样,你不想要一对密钥和金额对的列表吗?或者您要重用与单个帐户相同的类,但作为聚合?如果是后者,这里有一些示例代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
不可否认,由于使用Dictionaryfor for lookup,这里的额外效率将毫无意义,除非你有相当多的帐户......
编辑:如果你的评论中有少量帐户,你可以使用:
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;
}
Run Code Online (Sandbox Code Playgroud)