IEnumerator<T> GetNth<T>(List<T> list, int n) {
for (int i=0; i<list.Count; i+=n)
yield return list[i]
}
我认为没有必要使用 Linq 或者 lambda 表达式。
编辑:
赶紧的
public static class MyListExtensions {
public static IEnumerable<T> GetNth<T>(this List<T> list, int n) {
for (int i=0; i<list.Count; i+=n)
yield return list[i];
}
}
你用林奇的方式写作
from var element in MyList.GetNth(10) select element;
第二次编辑 :
让它更像林奇
from var i in Range(0, ((myList.Length-1)/n)+1) select list[n*i];
我认为,如果您提供了 linq 扩展,那么您应该能够在最不具体的接口上进行操作,因此可以在 IEnumable 上进行操作。当然,如果你的速度特别是大 N,你可能会提供一个索引访问超载。后者消除了对大量不需要的数据进行迭代的需要,并且比 Where 子句快得多。提供两个重载可以让编译器选择最合适的变量。
public static class LinqExtensions
{
public static IEnumerable<T> GetNth<T>(this IEnumerable<T> list, int n)
{
if (n < 0)
throw new ArgumentOutOfRangeException("n");
if (n > 0)
{
int c = 0;
foreach (var e in list)
{
if (c % n == 0)
yield return e;
c++;
}
}
}
public static IEnumerable<T> GetNth<T>(this IList<T> list, int n)
{
if (n < 0)
throw new ArgumentOutOfRangeException("n");
if (n > 0)
for (int c = 0; c < list.Count; c += n)
yield return list[c];
}
}
public static IEnumerable<T> GetNth<T>(this IEnumerable<T> list, int n) {
if (n <= 0) throw new ArgumentOutOfRangeException(nameof(n), n, null);
int i = n;
foreach (var e in list) {
if (++i < n) { //save Division
continue;
}
i = 0;
yield return e;
}
}
public static IEnumerable<T> GetNth<T>(this IReadOnlyList<T> list, int n
, int offset = 0) { //use IReadOnlyList<T>
if (n <= 0) throw new ArgumentOutOfRangeException(nameof(n), n, null);
for (var i = offset; i < list.Count; i += n) {
yield return list[i];
}
}