Sampling a list with linq
I need a helper method for adding axis labels to a chart. I don't want to add a label at every point along the axis that has values in the chart because that would get too busy. So I need to extract samples at regular intervals. So far I've come up with the following method which meets the requirements but I think there must be a neater way of accomplishing this with Linq. Can anyone think of how this could be made more concise (n represents the total number of samples I want back)?
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 开发者_如何学JAVA== i/divisor)
samples.Add(list[i]);
return samples;
}
Hm, what about:
return Enumerable.Range(0,n).Select(i=>list[(i*list.Count)/(n-1)]);
Not that it really matters, but this gives you a slightly better complexity (O(n)
instead of O(list.Count)
If I understand correctly:
int divisor = list.Count / n;
return list.Where((val, index) => index % divisor == 0).ToList();
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();
}
Try
list.Where((o, index) => index % divisor == 0)
This solution avoids using division in the iteration, which should perform faster.
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;
}
}
精彩评论