我有这个代码
private static void Count(List<DataRowSet> rows, int id, ref int count)
{
foreach (DataRowSet row in rows) {
if (row.parentId == id) {
count++;
Count(rows, row.Id, ref count);
}
}
}
和这个班
public class DataRowSet
{
public int Id;
public int parentId;
public DataRowSet(int id, int parent)
{
this.Id = id;
this.parentId = parent;
}
}
我想计算具有特定ID的List<DataRowSet>
的每个孩子。
Count(dataList, 1, ref cnt);
那行得通,但是一旦我在dataList
中有8000多个条目,就会发生StackOverflow异常。代码也很慢,大约需要1.5秒才能找到所有条目。
我该如何解决?
参考方案
StackOverflowException
发生是因为您的递归太深了。它可以正常工作到8000,上面的所有内容对于堆栈来说实在太多了。
您可以通过使用Stack<DataRowSet>
并将项目推入其中来解决此问题,而不是递归调用该函数。
查看您的DataRowSet
类似乎是一个简单列表,因此有一种简单的方法可以通过使用ILookup<int, DataRowSet>
来提高性能。这样,您可以使用键查找任何相关项,而不必一次又一次地遍历列表。
首先,您必须将顶级项目压入堆栈。可以这样完成。
Stack<DataRowSet> stack = new Stack<DataRowSet>(
dataRows.Where(x => x.Id == id));
使用dataRows.ToLookup
,可以按条目的ParentId
对其分组。
ILookup<int, DataRowSet> dataLookup = dataRows.ToLookup(x => x.parentId);
之后,您只需要遍历stack
直到其为空,同时推送具有正确ID的新项目。
while (stack.Count > 0) {
DataRowSet currentRow = stack.Pop();
foreach (DataRowSet rowSet in dataLookup[currentRow.Id]) {
stack.Push(rowSet);
}
}
这样,您就不必再担心StackOverflowException
了,并且性能也得到了提高。
总体而言,您的新功能将看起来像这样。
private static int Count(List<DataRowSet> dataRows, int id)
{
int totalDescendants = 0;
Stack<DataRowSet> stack = new Stack<DataRowSet>(
dataRows.Where(x => x.Id == id));
ILookup<int, DataRowSet> dataLookup = dataRows.ToLookup(x => x.parentId);
while (stack.Count > 0) {
DataRowSet currentRow = stack.Pop();
foreach (DataRowSet rowSet in dataLookup[currentRow.Id]) {
totalDescendants++;
stack.Push(rowSet);
}
}
return totalDescendants;
}
可以这样称呼
int cnt = Count(dataList, 1);
C#Linq可空INT字段包含在List <int>中SQL转换 - c#我有一张表格,其中列出了需要管理员签名的表单,而我想要做的就是将表单列表过滤到他们可以签名的表单。我得到了他们所管理的员工列表,然后将其放入员工ID列表中。var staffIds = manager.Staff.Select(x => x.Id).ToList(); 然后,我使用人员列表过滤表单列表。我得到了所有与经过身份验证的组织ID相匹配的表单,…
在PHP中使用long int - php我正在尝试此方法,但无法存储较大的价值$var = rand(100000000000000,999999999999999); echo $var; // prints a 9 digit value(largest possible) 如何获得期望值? 参考方案 PHP整数通常为32位。其他软件包提供了更高精度的整数:http://php.net/man…
使用jquery计算<id>中的总图像 - php我有一个div,里面有一些图像,例如<img src= etc我想计算该div中的图像总数。我也想使用PHP将这些图像ID保存到mysql中...谢谢 参考方案 要计算它们,您可以执行以下操作:alert($('#myDiv img').length); 要将所有id捕获到数组中,可以执行以下操作:var ids = []; $(&…
剃刀付款集成->如何通过关闭按钮X检测剃刀付款模型是否关闭 - javascript当用户关闭而无需付款时,我在CI框架中使用Razorpay,请创建razor支付模型,然后取消订单,我希望按状态更改为已取消的状态触发查询。所以我怎么能检测到这一点。我已经通过单击jQuery单击关闭功能但无法使用... javascript大神给出的解决方案 Razorpay提供了JS方法来检测模式关闭。您编写的任何JS代码都不会在结帐页面上运行,因为它是…
如何使用箭头符号(->)创建受保护的方法? - java当我们编写以下代码时Stream.of(1,2,3,4,5).filter(i -> (i%2 == 0)).map( i -> i*i ); 表达式i -> (i%2 == 0)或i -> i*i将变为私有方法。在我的用例中,编写了一个junit测试,以确保没有方法是私有的(是的,这是强制性的),并且对于这些lambda表达式而言,…