2011-04-16 96 views
2

我正在查找LINQ查詢,該查詢將僅選擇那些日期間隔不超過20秒的對象。例如:LINQ按日期間隔獲取對象

AuthenticationEssay[] essays = new AuthenticationEssay[] { 
    new AuthenticationEssay() { Date = DateTime.Now.AddSeconds(20), Success = false }, 
    new AuthenticationEssay() { Date = DateTime.Now.AddSeconds(24), Success = false }, 
    new AuthenticationEssay() { Date = DateTime.Now.AddSeconds(29), Success = false }, 
    new AuthenticationEssay() { Date = DateTime.Now.AddSeconds(38), Success = false }, 
    new AuthenticationEssay() { Date = DateTime.Now.AddSeconds(125), Success = false }, 
    new AuthenticationEssay() { Date = DateTime.Now.AddSeconds(347), Success = false }, 
    new AuthenticationEssay() { Date = DateTime.Now.AddSeconds(400), Success = false }, 
    new AuthenticationEssay() { Date = DateTime.Now.AddSeconds(422), Success = false }, 
    new AuthenticationEssay() { Date = DateTime.Now.AddSeconds(446), Success = false }, 
    new AuthenticationEssay() { Date = DateTime.Now.AddSeconds(467), Success = false } 
}; 

我想只選擇那些對象,它們的日期間隔的第一次出現是不大於針對下一個對象20秒。在這種情況下,查詢應只返回前4個對象。任何想法? :(

UPDATE

對不起,我忘了提,我被按降序排序的數組。所以,是的,在陣列中的位置應該不會對查詢產生任何影響。

+0

如果最後一項是「AddSeconds(465)',而不是將它包括在內? – 2011-04-16 19:14:24

+1

你的意思是日期間隔不超過20秒?你的意思是DateTime.Now和essay [i] .Date之間的區別嗎?你是指短文[0]和短文[1]之間的意思? – mfanto 2011-04-16 19:14:26

+0

我的意思是散文[0]和散文[1]之間。但在做出一些比較之前,我正在對數組進行排序 – Davita 2011-04-16 19:26:34

回答

1

這個怎麼樣

var query from i in Enumerable.Range(1, count - 1) 
      let current = list[i] 
      let previous = list[i - 1] 
      // I see some empty positions in your example, nullability check 
      where current != null && previous != null 
      where (current.Date - previous.Date).TotalSeconds < 20 
      select previous; 

編輯:?很明顯,你必須調用First()爲了只獲取序列的第一個元素

query.First(); 

編輯2:我剛剛看過你訂購你的結果降序。在這種情況下,查詢會稍有不同:

var query from i in Enumerable.Range(1, count - 1) 
      let current = list[i] 
      let previous = list[i - 1] 
      // I see some empty positions in your example, nullability check 
      where current != null && previous != null 
      where (previous.Date - current.Date).TotalSeconds < 20 
      select current; 
+0

不,不起作用。它返回太多不應該在列表中的對象 – Davita 2011-04-16 19:38:59

+0

如果您只想要第一個元素,請在此LINQ查詢上調用'First()'方法。 – 2011-04-16 19:40:37

+0

謝謝,但我知道如何得到元素的第一次出現。我想要的是首次發生日期間隔不超過20秒的元素。 – Davita 2011-04-16 19:49:27

0

它不漂亮,但在這裏你去...

var result = Enumerable.Range(0, essays.Count() - 1) 
    .Select(i => new {Essays1 = essays[i], Essays2 = essays[i + 1]}) 
    .Where(a => a.Essays2 != null) 
    .Where(a => a.Essays2.Date - a.Essays1.Date < new TimeSpan(0, 0, 0, 20)) 
    .Select(a => a.Essays1); 

是否必須是LINQ?我愛LINQ,但我認爲這樣的事情會更可讀......

var result = new List<AuthenticationEssay>(); 
for (var i = 0; i < (essays.Count() - 1); i++) 
{ 
    if (essays[i + 1] != null) 
     if (essays[i + 1].Date - essays[i].Date < new TimeSpan(0, 0, 0, 20)) 
      result.Add(essays[i]); 
} 
0

中很可能使用做內置的LINQ的運營商,但在這種情況下,我覺得寫一個特定的方法是比較容易。你可以做這樣的事情:

static IEnumerable<AuthenticationEssay> Filter(IEnumerable<AuthenticationEssay> list) 
{ 
    AuthenticationEssay last = null; 
    AuthenticationEssay previous = null; 
    foreach(var item in list) 
    { 
     if (last == null) 
     { 
      // Always return the first item 
      yield return item; 
     } 
     else if ((item.Date - last.Date).TotalSeconds >= 20) 
     { 
      yield return item; 
     } 

     previous = last; 
     last = item; 
    } 
    if (previous != null && last != null && (last.Date - previous.Date).TotalSeconds <= 20) 
     yield return last; 
} 

當然,這將有可能使其更可反覆使用,使得該方法的通用和傳遞一個謂詞作爲參數,但因爲它是一個非常具體的要求,我不知道它會非常有用...

相關問題