List<> 上的递归循环导致堆栈溢出
我有一个包含两个字符串和一个日期时间的对象的List<>
。我想使用两个字符串作为键和最后一个 DateTime 值构建仅包含最后一个唯一项目的相同对象的另一个列表。在 SQL 中,请考虑以下内容:
SELECT col1, col2, MAX(datetime) FROM table GROUP BY col1, col2
这给出了 col1、col2 和最后日期时间的唯一列表。所以..我试图在带有两个列表的代码中执行此操作。其中包含重复项,仅解析并抓取最后一个唯一的项目以填充第二个列表。
我拥有的数据集很大,所以只需浏览重复列表,然后检查该项目是否在唯一列表中,如果没有添加它,如果是,比较日期等......是相当慢的。所以我想我可以递归地遍历重复列表并抓住唯一的项目找到它们的最大日期时间并在循环时删除非最大的项目,使我的重复列表越来越小,从而加快速度。 (我希望你仍然关注我..)
所以无论如何。我编写了一个包含两个列表的递归循环,但是当我循环遍历时,我在大约第 3000 次迭代时收到了 System.StackOverflowException 异常。
这是我的代码。想象一下 ListWithDuplicates
充满了数据。实际的 ListDataItem
有更多我遗漏的属性。但我的主要问题是为什么我不能以这种方式循环访问公共列表而不导致 StackOverflowException ?
using System;
using System.Net;
using System.IO;
using System.Collections.Generic;
using System.Linq;
public class RecursionTest
{
public List<listDataItem> ListWithDuplicates { get; set; }
public List<listDataItem> ListWithUniques { get; set; }
public RecursionTest()
{
Process();
}
public void Process()
{
int rowcount = 0;
int duplicates = 0;
int total = 0;
RecursiveLoopForUnique(ref rowcount, ref duplicates, ref total, "", "");
}
private void RecursiveLoopForUnique(ref int rowcount, ref int duplicates, ref int total, string col1, string col2)
{
if (rowcount > 0)
duplicates += ListWithDuplicates.RemoveAll(z => z.COL1 == col1 && z.COL2 == col2);
if (ListWithDuplicates.Count > 0)
{
foreach (listDataItem item in ListWithDuplicates)
{
rowcount++;
if (ListWithUniques.FindAll(z => z.COL1 == item.COL1 && z.COL2 == item.COL2).Count < 1)
{
ListWithUniques.Add(ListWithDuplicates.FindAll(z => z.COL1 == item.COL1 && z.COL2 == item.COL2).OrderByDescending(z => z.DATETIME).First());
col1 = item.COL1;
col2 = item.COL2;
break;
}
}
RecursiveLoopForUnique(ref rowcount, ref duplicates, ref total, col1, col2);
}
else
return;
}
public class listDataItem
{
public string COL1 { get; set; }
public string COL2 { get; set; }
public DateTime DATETIME { get; set; }
public listDataItem(string col1, string col2, DateTime datetime)
{
COL1 = col1;
COL2 = col2;
DATETIME = datetime;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
怎么样:
我在一个包含 2 个唯一的 col1/col2 对各 1000 个的列表上对此进行了测试。工作正常并且比 LINQ groupby/select 更快。
How about this:
I tested this on a list containing 1000 each of 2 unique col1/col2 pairs. Worked fine and was faster than a LINQ groupby/select.
LINQ,是的。
MSDN 注释..
其中:http://msdn.microsoft.com/en -us/library/bb534803.aspx
最大:http:// msdn.microsoft.com/en-us/library/bb347632.aspx
订购者:http://msdn.microsoft.com/en-us/library/bb534966.aspx
最后:http://msdn.microsoft.com/en-us/library/bb358775.aspx
LINQ, yay.
MSDN notes on..
Where: http://msdn.microsoft.com/en-us/library/bb534803.aspx
Max: http://msdn.microsoft.com/en-us/library/bb347632.aspx
OrderBy: http://msdn.microsoft.com/en-us/library/bb534966.aspx
Last: http://msdn.microsoft.com/en-us/library/bb358775.aspx
我不确定语法,但应该很接近。
I'm not sure about the syntax, but it should be close.
好吧,如果您有超过几千对独特的 C1、C2,那么您就会遇到这种情况,因为您要为每个独特的组递归一次。
有很多方法可以解决这个问题;一种更清晰、更快速的方法是按 C1 和 C2 对列表进行排序,然后精确地向下查找一次以查找每组中的最新日期。如果您不想自己重新实现它,最好的方法是:
Well, if you have more than a few thousand unique pairs of C1, C2, then you'll encounter this, since you're recursing once for each unique group.
There are a lot of ways you could fix this up; one that would wind up much clearer and faster would be to sort the list by C1 and C2, and then go down it exactly once to find the most recent date in each group. If you aren't wedded to reimplementing it yourself, the best way is this:
在 LINQ 中:
并且以一种可能更有用的形式:
然后您可以像这样引用它:
in LINQ:
And in a potentially more useful form:
Then you can reference it like so: