使用linq对列表进行采样

时间:2010-12-14 13:29:50

标签: c# linq algorithm

我需要一个辅助方法来将轴标签添加到图表中。我不想在图表中具有值的轴的每个点添加标签,因为这会太忙。所以我需要定期提取样品。到目前为止,我已经提出了满足要求的以下方法,但我认为必须有一种更简洁的方法来实现Linq。谁能想到如何使这更简洁(n代表我想要的样本总数)?

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;
}

5 个答案:

答案 0 :(得分:5)

嗯,嗯,怎么样:

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

这并不重要,但这会让您的复杂性稍微提高一些(O(n)而不是O(list.Count)

答案 1 :(得分:3)

如果我理解正确:

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

答案 2 :(得分: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();
    }

答案 3 :(得分:0)

尝试

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

答案 4 :(得分: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;
    }
}