2011-05-13 89 views
2

我有號碼的清單,我想選擇有一定規模的滑動窗口:列表視圖推拉窗

List<double> lst = {3,78,24,25,634,25,478,24}; 
int WindowSize = 4; 

index = 0: return {3}; 
index = 1: return {3,78}; 
index = 2: return {3,78,24}; 
index = 3: return {3,78,24,25}; 
index = 4: return {78,24,25,634}; 
index = 5: return {24,25,634,25}; 
index = 6: return {25,634,25,478}; 
index = 7: return {634,25,478,24}; 

這是並不難的一個概念,但我正在努力用.Skip() .Take()擴展方法來完成。是否有更簡單的方法在項目前面選擇WindowSize條目,而不是試圖找到起點位置,然後獲取下一個WindowSize條目?我試圖想到一個更簡單的方法來做到這一點,而不是所有的邊界檢查與Skip()Take()需要檢查。

您可以將列表反轉,然後執行Count() - 索引,然後執行Take(),但看起來效率不高。

回答

3

我想這將需要最小限度的檢查 - 只是基本的理智檢查。看看是否有效

IEnumerable<double> GetWindow(List<double> lst, int index, int windowSize) { 
    if(index >= lst.Length){ 
     // Throw proper exception 
    } 
    return lst.Skip(index-windowSize).Take(Math.Min(index,windowSize)); 
} 
+2

,你可以簡單地使用跳過(索引windowSize),負值會被忽略和0 – Alexander 2011-05-13 04:10:03

+0

@Alexander處理是的,你是對的- 我錯過了。糾正。謝謝。 – YetAnotherUser 2011-05-13 04:13:39

0

如果你只想得到一個窗口,你接受的答案看起來合適。 但對於迭代多於一個窗口,我會像這樣去:

public static IEnumerable<IEnumerable<TSource>> Window<TSource>(
    this IEnumerable<TSource> source, int size) 
{ 
    var q = new Queue<TSource>(size); 

    foreach (var value in source) 
    { 
     if (q.Count >= size) 
      q.Dequeue(); 
     q.Enqueue(value); 
     yield return q; 
    } 
}