Ответ 1
return list.Where((x, i) => i % nStep == 0);
Я использую .NET 3.5 и хотел бы получить каждый * n
* -й элемент из списка. Я не беспокоюсь о том, достигнуто ли это с помощью лямбда-выражения или LINQ.
Edit
Похоже, этот вопрос вызвал довольно много дебатов (что хорошо, правда?). Главное, что я узнал, это то, что, когда вы думаете, что знаете каждый способ сделать что-то (даже так просто), подумайте еще раз!
return list.Where((x, i) => i % nStep == 0);
Я знаю это "старая школа", но почему бы просто не использовать цикл for с stepping = n?
Звучит как
IEnumerator<T> GetNth<T>(List<T> list, int n) {
for (int i=0; i<list.Count; i+=n)
yield return list[i]
}
сделал бы трюк. Я не вижу необходимости использовать Linq или лямбда-выражения.
EDIT:
Сделать это
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];
}
}
и вы пишете LINKish способом
from var element in MyList.GetNth(10) select element;
2nd Edit:
Чтобы сделать его еще более LINQish
from var i in Range(0, ((myList.Length-1)/n)+1) select list[n*i];
Вы можете использовать Перегрузку Where, которая передает индекс вместе с элементом
var everyFourth = list.Where((x,i) => i % 4 == 0);
Для цикла
for(int i = 0; i < list.Count; i += n)
//Nth Item..
Я не уверен, возможно ли это сделать с выражением LINQ, но я знаю, что для этого можно использовать метод расширения Where
. Например, чтобы получить каждый пятый элемент:
List<T> list = originalList.Where((t,i) => (i % 5) == 0).ToList();
Это получит первый элемент и каждую пятую оттуда. Если вы хотите начать с пятого элемента вместо первого, вы сравниваете с 4 вместо сравнения с 0.
Я думаю, что если вы предоставите расширение linq, вы сможете работать с наименее определенным интерфейсом, таким образом, на IEnumerable. Конечно, если вы предпочитаете скорость, особенно для большого 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];
}
}
private static readonly string[] sequence = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15".Split(',');
static void Main(string[] args)
{
var every4thElement = sequence
.Where((p, index) => index % 4 == 0);
foreach (string p in every4thElement)
{
Console.WriteLine("{0}", p);
}
Console.ReadKey();
}
Выход