2009-05-05 89 views
1

我有一個小問題,我想在linq列表中找到下一個「活動」項目。然後下一個「活動」項目由startDate和EndDate定義。這是一個示例列表。如何使用LINQ獲取列表中的下一個活動項目

//-- Create Lists of turns  
    IList<Turn> turns= new List<Turn>(){ 
       new Turn(){Name = "Turn 1", StartDate = DateTime.Parse("2009-05-01"), EndDate = DateTime.Parse("2009-05-01") } 
     ,  new Turn(){Name = "Turn 2", StartDate = DateTime.Parse("2009-06-01"), EndDate = DateTime.Parse("2009-06-01") } 
     ,  new Turn(){Name = "Turn 3", StartDate = DateTime.Parse("2009-07-01"), EndDate = DateTime.Parse("2009-07-02") } 
     ,  new Turn(){Name = "Turn 4", StartDate = DateTime.Parse("2009-08-01"), EndDate = DateTime.Parse("2009-08-03") } 
    } 

//-- Get the next Turn by DateTime. 
DateTime toDay = DateTime.Parse("2009-06-02"); 

//-- Should return the "Turn 3" item... 
Turn turn = (from item in turns 
      where ..... 
      select turn).FirstOrDefault<Turn>(); 

是否有一個很好的解決方案,通過在Turn上使用startDate/endDate屬性來查找下一個回合。我已經試着首先用startdate命令列表,並在列表中找到第一個列表,但如果有更安全的方法來獲取它,那麼不需要以正確順序找到正確的列表,以找到正確的Turn。

+0

我已經說了一個解決方案,但是您可以更具體的條款來選擇合適的轉,請嗎? – Noldorin 2009-05-05 14:15:33

回答

0

爲什麼你不能在今天之後得到第一個包含開始日期的項目?我添加了一個明確的OrderBy()調用,以確保列表已排序。如果你知道它是排序的,當然你可以把它排除在外。

turns.OrderBy(t => t.StartDate).FirstOrDefault(t => t.StartDate > today); 

UPDATE

我錯過了你的最後幾行。是的,你可以做到這一點,而無需明確排序列表。您必須在今天之後搜索具有開始日期的項目列表,並且它必須不是在今天之後但在當前項目的開始日期之前沒有開始日期的項目。但是這樣會減慢搜索速度,因爲你必須查看每個產生O(n2)的項目的整個列表。

turns.Single(t => 
    t.StartDate > today && 
    turns.All(u => u.StartDate <= today || u.StartDate > t.StartDate)) 

這裏假設圈不重疊。如果它們重疊,則必須使用First而不是Single或添加其他約束以獲得唯一結果。 最後:使用分揀解決方案 - 這種解決方案絕不比分揀和獲取第一件物品更安全。

0

我覺得你只是想:

var turn = turns.SkipWhile(t => t.EndDate < today).FirstOrDefault(); 

這將返回包含或給定日期today,你似乎什麼在尋找後第一個彎道。當然,它還假定您的turns列表已經排序。

編輯:看來我錯過了不想排序的列表。我仍然不能完全確定你需要選擇適當的轉彎的條件,這將使我能夠改善查詢。

+0

如果列表未排序,這可能會失敗 - 您只需在今天之後返回第一個項目,但不一定是今天之後的第一個項目。 – 2009-05-05 14:08:29

+0

@丹尼爾:是的,很清楚。但問題中的例子顯示他的列表已經排序,所以我真的在迴應。無論如何他都提到了分類,所以他顯然意識到了這個問題。儘管如此,我仍然會加上警告。 – Noldorin 2009-05-05 14:12:29

+0

你犯了同樣的錯誤 - 錯過了問題的最後幾行。他正在尋找一種方法來獲取下一個項目,但沒有先排序列表,因爲他似乎不相信排序算法。 – 2009-05-05 14:17:36

1

你可以這樣做。

Turn turn = turns 
    .Where(t => t.StartDate >= toDay) 
    .OrderBy(t => t.StartDate) 
    .FirstOrDefault(); 

Where調用是可選的 - 其目標是減少必須訂購的項目數量。

相關問題