1

我看到一些我很难理解的行为。给定一个DateTimes 列表,我只想按降序选择过去一年中出现的日期。但是使用OrderBy(), OrderByDescending(), andSkipWhile()的行为……很奇怪。给定从今天开始的列表,包括过去 100 个月,如下所示:

List<DateTime> ldt = new List<DateTime>();
for (int i = 0; i < 100; i++)
{
    ldt.Add(DateTime.Now.AddMonths(-i));
}

我从以下代码开始:

ldt = ldt.OrderByDescending(date => date).
          SkipWhile(date => date <= DateTime.Now.AddYears(-1)).ToList();

这会正确排序列表,但不会跳过任何记录。所以为了好玩,我尝试了这个(比今天更早地跳过所有内容,即所有内容):

 ldt = ldt.OrderByDescending(date => date).
            SkipWhile(date => date <= DateTime.Now).ToList();

哪个有效。该列表为空。然后我尝试了以下(OrderBy 而不是 OrderByDescending):

ldt = ldt.OrderBy(date => date).
          SkipWhile(date => date <= DateTime.Now.AddYears(-1)).ToList(); 

完全按预期工作 - 列表已排序,日期已正确过滤。因此,有效的最终结果是:

ldt = ldt.OrderBy(date => date).
          SkipWhile(date => date <= DateTime.Now.AddYears(-1)).ToList();
ldt = ldt.OrderByDescending(date => date).ToList();

跳过,然后重新排序。那么我错过了什么?为什么其中一些有效,而另一些则以不可预知的方式中断?对于我正在尝试做的事情,正确的一行命令是什么?

4

2 回答 2

5

基本上,你想要TakeWhile而不是SkipWhile

ldt = ldt.OrderByDescending(date => date)
         .TakeWhile(date => date > DateTime.Now)
         .ToList();

使用后OrderByDescending,您要保留的条目是第一个条目......而SkipWhile假设您要丢弃一些条目,然后保留其余条目。

(或者你可以使用过滤器Where然后排序,正如 Reed 建议的那样。两者都可以工作 Reed 的可能更有效。使用你觉得更容易理解的任何一个。)

当您对这样的事情感到困惑时,有时值得在一张纸上写下数据示例。计算出每一步之后的序列是什么样的,然后下一步会做什么。

于 2013-05-29T21:22:56.913 回答
4

我只想选择过去一年发生的日期

而不是 using SkipWhile,您应该能够使用.Where

 ldt = ldt.Where(date => date.> DateTime.Now.AddYears(-1))
        .OrderByDescending(date => date).ToList();
于 2013-05-29T21:23:20.480 回答