2017-07-02 28 views
1

我需要過濾來自Dictionary<DateTime, int>的數據以獲取僅後面的DateTime's之間的差異爲1分鐘或更長的元素。c#linq過濾器字典<日期時間,int>按預定義的最小時間差

例如,在字典中我能有這樣的兩雙數據:

var pairs = new Dictionary<DateTime, int>() 
{ 
    { new DateTime(2010, 01, 20, 19, 05, 00), 10 }, 
    { new DateTime(2010, 01, 20, 19, 05, 19), 11 }, 
    { new DateTime(2010, 01, 20, 19, 05, 49), 12 }, 
    { new DateTime(2010, 01, 20, 19, 06, 05), 13 }, 
    { new DateTime(2010, 01, 20, 19, 07, 05), 14 }, 
    { new DateTime(2010, 01, 20, 19, 07, 55), 15 }, 
}; 

什麼,我想作爲過濾的結果是:在字典

<2010-01-20 19:05:00, 10> 
<2010-01-20 19:06:05, 13> 
<2010-01-20 19:07:05, 14>` 

DateTime鍵按升序爲了不需要重新排序,但我會需要它非常有效,因爲很多數據將被處理。

你能介紹一些很好的LINQ查詢嗎?

+2

'在字典中的DateTime鍵按升序排列,所以沒有必要reorder'你還是應該對它們進行排序。根據文檔,「返回項目的順序未定義。」(https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx)。它今天有效,明天可能會突破。 –

+1

另外,如果你想要高效,Linq通常不是正確的解決方案 –

+0

那麼你想要一個數組的數組,其中的時間是分開的? – LiverpoolOwen

回答

5

我想說這是Linq的不好的候選人。我會去一個簡單枚舉:

public static IEnumerable<KeyValuePair<DateTime, int>> Filter(IEnumerable<KeyValuePair<DateTime, int>> values) 
{ 
    KeyValuePair<DateTime, int>? previous = null; 

    foreach (var kvp in values.OrderBy(v => v.Key)) 
    { 
     if (previous == null || (kvp.Key - previous.Value.Key).TotalMinutes >= 1) 
     { 
      previous = kvp; 
      yield return kvp; 
     } 
    } 
} 

然後,只需枚舉它,做任何你需要的結果:

foreach (var value in Filter(dictionary)) 
{ 
    Console.WriteLine($"{value.Key} - {value.Value}"); 
} 

只是爲了好玩,一個LINQ版本(請,請不要使用它):

public static IEnumerable<KeyValuePair<DateTime, int>> FilterLinq(IEnumerable<KeyValuePair<DateTime, int>> values) 
{ 
    KeyValuePair<DateTime, int>? previous = null; 

    return from kvp in values 
      orderby kvp.Key 
      where previous == null || (kvp.Key - previous.Value.Key).TotalMinutes >= 1 
      select (previous = kvp).Value; 
} 
+0

謝謝,我會試試看。 – pitersmx

2

我建議LINQ是go在這裏選擇。維護通常很容易,而且往往不會有任何性能損失可以忽略不計。

試試這個:

var filtered = 
    pairs.Skip(1).Aggregate(pairs.Take(1).ToList(), (a, p) => 
    { 
     if (p.Key.Subtract(a.Last().Key).TotalMinutes >= 1.0) 
     { 
      a.Add(p); 
     } 
     return a; 
    }).ToList(); 

這給:

filtered

+2

很高興知道'Aggregate'更強大,我想:) –