How can I get every nth item from a List<T>?

Viewed 91505

I'm using .NET 3.5 and would like to be able to obtain every *n*th item from a List. I'm not bothered as to whether it's achieved using a lambda expression or LINQ.

Edit

Looks like this question provoked quite a lot of debate (which is a good thing, right?). The main thing I've learnt is that when you think you know every way to do something (even as simple as this), think again!

10 Answers
return list.Where((x, i) => i % nStep == 0);

I know it's "old school," but why not just use a for loop with stepping = n?

Sounds like

IEnumerator<T> GetNth<T>(List<T> list, int n) {
  for (int i=0; i<list.Count; i+=n)
    yield return list[i]
}

would do the trick. I do not see the need to use Linq or a lambda expressions.

EDIT:

Make it

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

and you write in a LINQish way

from var element in MyList.GetNth(10) select element;

2nd Edit:

To make it even more LINQish

from var i in Range(0, ((myList.Length-1)/n)+1) select list[n*i];

You can use the Where overload which passes the index along with the element

var everyFourth = list.Where((x,i) => i % 4 == 0);

For Loop

for(int i = 0; i < list.Count; i += n)
    //Nth Item..

I'm not sure if it's possible to do with a LINQ expression, but I know that you can use the Where extension method to do it. For example to get every fifth item:

List<T> list = originalList.Where((t,i) => (i % 5) == 0).ToList();

This will get the first item and every fifth from there. If you want to start at the fifth item instead of the first, you compare with 4 instead of comparing with 0.

Imho no answer is right. All solutions begins from 0. But I want to have the real nth element

public static IEnumerable<T> GetNth<T>(this IList<T> list, int n)
{
    for (int i = n - 1; i < list.Count; i += n)
        yield return list[i];
}

@belucha I like this, because the client code is very readable and the Compiler chooses the most efficient Implementation. I would build upon this by reducing the requirements to IReadOnlyList<T> and to save the Division for high-performance LINQ:

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