OrderBy [Descending]()和SkipWhile()的意外行为

时间:2013-05-29 21:20:54

标签: c# linq

我看到一些我很难理解的行为。给定DateTime的列表,我只想按降序选择过去一年中发生的日期。但是使用OrderBy()OrderByDescending()SkipWhile()表现得很奇怪。给出从今天开始的列表,包括过去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();

跳过,然后重新订购。那我错过了什么?为什么其中一些工作,有些突破不可预测的方式?对于我正在尝试做的事情,正确的一行命令是什么?

2 个答案:

答案 0 :(得分:5)

基本上,您需要TakeWhile而不是SkipWhile

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

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

(或者您可以使用Where进行过滤,然后按照Reed的建议进行排序。两者都可以使用Reed可能更有效。使用您认为更难理解的任何一种。)

当你对这样的事情感到困惑时,有时候值得在一张纸上写出数据的例子。计算出每个步骤后序列的样子,然后确定下一步的步骤。

答案 1 :(得分:4)

  

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

您应该可以使用SkipWhile

,而不是使用.Where
 ldt = ldt.Where(date => date.> DateTime.Now.AddYears(-1))
        .OrderByDescending(date => date).ToList();