C#列表 - 分组依据 - 如果没有的Linq [英] C# List - Group By - Without 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屋!