2010-12-14 58 views
3

我需要一個輔助方法來爲圖表添加軸標籤。我不想在軸上的每個點上添加一個標籤,因爲那樣會太忙。所以我需要定期提取樣本。到目前爲止,我已經提出了滿足要求的以下方法,但我認爲必須有一個更好的方式來與Linq一起完成此任務。任何人都可以想到如何使它更加簡潔(n代表我想要的樣本總數)?用linq對列表進行抽樣

public static List<T> Sample<T>(this List<T> list, int n) 
{ 
    var samples = new List<T>(); 
    var divisor = list.Count/n; 
    for (var i = 0; i < list.Count; i++) 
    if (samples.Count == i/divisor) 
     samples.Add(list[i]); 
    return samples; 
} 
+3

你確定採樣會給一個不錯的軸?我會尋找最小值和最大值,並使用log10算法構建一個比例。大多數圖表工具會這樣做。 – 2010-12-14 13:52:46

+0

@亨克霍特曼,看了看輸出結果,我傾向於同意你的看法。 – grenade 2010-12-14 14:14:29

+0

採樣是解決此問題的錯誤方法。我會留下這個問題,因爲有一天有些人會需要一個採樣器來處理別的事情,但最終我確實使用了上面的建議。你可以在這裏看到結果:http://stackoverflow.com/questions/25458/how-costly-is-reflection-really/4440657#4440657 – grenade 2010-12-14 17:23:45

回答

4

嗯,怎麼樣:

return Enumerable.Range(0,n).Select(i=>list[(i*list.Count)/(n-1)]); 

不是我但這會給你帶來更好的複雜性(O(n)而不是O(list.Count)

+0

雖然代碼不可讀,但我確實喜歡這個主意。 – Kobi 2010-12-14 13:41:58

3

如果我理解正確:

int divisor = list.Count/n; 
return list.Where((val, index) => index % divisor == 0).ToList(); 
0

嘗試

list.Where((o, index) => index % divisor == 0) 
+0

我認爲,你的意思是「列表」而不是「樣本」... – MartinStettner 2010-12-14 13:41:28

+0

是的,謝謝.... – Aliostad 2010-12-14 13:43:34

2
public static List<T> Sample<T>(this List<T> list, int n) 
    { 
     Int32 count = list.Count; 
     Int32 interval = count/n; 

     return list.Where((item, index) => index % interval == 0).ToList(); 
    } 
0

該解決方案避免了在迭代中使用除法,它應該更快地執行。

public static List<T> Sample<T>(this List<T> list, int n) 
{ 
    return list.Sample(list.Count/n).ToList(); 
} 

public static IEnumerable<T> Sample<T>(this IEnumerable<T> enumerable, int interval) { 
    var index = 0; 
    foreach (var item in enumerable) { 
     if (index == 0) { 
      yield return item; 
     } 
     if (++index == interval) index = 0; 
    } 
}