如何检查列表中是否已存在相同的日期?

use*_*831 2 c# datetime list

我有一个日期时间列表(有时间和日期),现在需要一个方法来将它所有独特的日子变成一个单独的列表
示例:

[1.1.2015 12:34]    [1.1.2015 12:34]   [1.1.2015 12:34]
[1.2.2015 4:34]     [1.2.2015 2:34]     [1.2.2015 1:34]
[1.3.2015 8:34]     [1.3.2015 1:34]     [1.6.2015 2:34]  
Run Code Online (Sandbox Code Playgroud)

需要变成:

[1.1.2015 0:0]    [1.2.2015 0:0]    [1.3.2015 0:0]    [1.6.2015 0:0]
Run Code Online (Sandbox Code Playgroud)

我该怎么做呢?

Ale*_*kov 7

DateTime.Date和Enumrable.Distinct是一个选项(假设您不需要保持顺序):

var dates = dateAndTimes.Select(d => d.Date).Distinct().ToList();
Run Code Online (Sandbox Code Playgroud)

Distinct 可能,但不必保留项目的顺序(我相信当前的实施将保持秩序).

如果您需要正式保证原始订单 - 重新排序(OrderBy)如果列表已经排序,或者重复原始列表中的项目并添加到列表中尚未列出的新列表(类似于Distinct内部,但与保证代码的行为).

请注意,根据Tim Schmelter的评论,使用类似的东西来保持项目的顺序newList.Contains(itemAboutToBeAdded)是非常慢的(并且因为您需要检查项目是否按当前正在构造的顺序而笨拙),使用常规foreach类似于以下将数学O(n )Distinct以及正式订单保证提供的表现:

 var dates = dateAndTimes.Select(d => d.Date);
 var alreadyInList = new HashSet<DateTime>();
 var datesInSameOrder = new List<DateTime>();
 foreach(var date in dates)
 {
    if (!alreadyInList.Contains(date))
    {
        alreadyInList.Add(date);
        datesInSameOrder.Add(date);
    }
 }
Run Code Online (Sandbox Code Playgroud)

可以编写更短的版本以依赖于如果项目已经存在则HashSet.Add返回的事实false:

var alreadyInList = new HashSet<DateTime>();
var datesInSameOrder = dates.Where(date => alreadyInList.Add(date)).ToList();
Run Code Online (Sandbox Code Playgroud)

或者即使依赖于项目顺序的实施细节HashSetAdd调用顺序相同(正式订单未定义,因此使用风险自负,Distinct具有相同的行为 - 因此没有任何好处):

 var datesInSameOrder = new HashSet<DateTime>(dates).ToList();
Run Code Online (Sandbox Code Playgroud)