У меня есть List<>
объектов, содержащих две строки и DateTime.Я хочу создать еще один список из тех же объектов, содержащий только последние уникальные элементы, используя две строки в качестве ключей и последнее значение DateTime.В SQL подумайте о следующем:
SELECT col1, col2, MAX(datetime) FROM table GROUP BY col1, col2
. Это дает уникальный список col1, col2 и даты последнего времени.Итак .. Я пытаюсь сделать это в коде с двумя списками.Один с дубликатами в нем, которые анализируют и извлекают только последние уникальные элементы из него, чтобы заполнить второй список.
Наборы данных, которые у меня есть, огромны, поэтому просто просматривая список дубликатов, затем проверяете, является ли элементв уникальном списке, если он не добавляется, сравнивать даты и т. д. довольно медленно.Поэтому я подумал, что могу рекурсивно просмотреть список дубликатов, найти уникальные элементы, найти их максимальное время и удалить не максимальные, когда я перебираю цикл, делая мой дубликат списка все меньше и меньше, тем самым ускоряя процесс.(Я надеюсь, что вы все еще следуете за мной ..)
Так или иначе.Я написал рекурсивный цикл с двумя списками, но при прохождении цикла я получаю System.StackOverflowException
о 3000-й итерации.
Вот мой код.Представьте, что ListWithDuplicates
полон данных.Фактический ListDataItem
имеет больше свойств, которые я пропустил.Но мой главный вопрос: почему я не могу циклически пройти через public list
, не вызывая 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;
}
}
}