删除列表中重复项的最佳性能和解决方案

时间:2016-06-13 11:35:37

标签: c# list

我有一个清单:

List<Test> = new List<Test>{
new Test{Name="Test", Date="2016-06-13 18:32:01.380"},
new Test{Name="Test2", Date="2016-06-13 18:32:29.117"},
new Test{Name="Test3", Date="2016-06-13 18:32:40.930"},
new Test{Name="Test3", Date="2016-06-13 18:32:51.517"},
new Test{Name="Test", Date="2016-06-13 18:33:06.477"},
.....
}

如何删除具有重复Name值的项目,同时保留唯一具有最新Date值的项目,同时实现最佳效果?

2 个答案:

答案 0 :(得分:4)

这至少是最具可读性的方法,并假设Date实际上是DateTime

tests = tests.GroupBy(t => t.Name)
    .Select(g => g.OrderByDescending(t => t.Date).First())
    .ToList();

这更有效:

var latestTests = new Dictionary<string, Test>(tests.Count);
foreach (Test t in tests)
{
    Test test;
    if (latestTests.TryGetValue(t.Name, out test))
    {
        if(test.Date < t.Date)
            latestTests[t.Name] = t;
    }
    else
    {
        latestTests.Add(t.Name, t);
    }
}
tests = latestTests.Values.ToList();

答案 1 :(得分:3)

我认为Tim提出的解决方案很好。 (第一个)你应该遵循KISS原则。

可是......

你可以为它创建一个`Dictionary'并查找每个项目。 我认为这将是最有效的。 这个只进行一次查找。

foreach(var searchItem in myList)
{
    Test item;
    if(myDict.TryGetValue(searchItem.Name, out item))
    {
        if(searchItem.Date > item.Date)
        {
            // swap the dates to keep the original objects intact (but this will change the order in the list.)
            var temp = item.Date;
            item.Date = searchItem.Date;
            searchItem.Date = temp;
        }
    }
    else
        // create a copy, you don't want to change the original
        myDict.Add(
            searchItem.Name, 
            searchItem);
}

您可以比较这些结果... groupby vs dictionary