Take every second object in the list

I have an IEnumerable and I want to get a new IEnumerable containing every nth element.

Can this be done in Linq?

+7
c # linq linq-to-objects
source share
3 answers

I just realized it myself ...

The IEnumerable<T>.Where() method has an overload that accepts the index of the current element - exactly what the doctor ordered.

 (new []{1,2,3,4,5}).Where((elem, idx) => idx % 2 == 0); 

It will return

 {1, 3, 5} 

Update. To cover both my use case and Dan Tao's suggestion, let's also indicate what the first returned item should be:

 var firstIdx = 1; var takeEvery = 2; var list = new []{1,2,3,4,5}; var newList = list .Skip(firstIdx) .Where((elem, idx) => idx % takeEvery == 0); 

... will return

 {2, 4} 
+23
source share

To implement Christie's proposal :

 public static IEnumerable<T> Sample<T>(this IEnumerable<T> source, int interval) { // null check, out of range check go here return source.Where((value, index) => (index + 1) % interval == 0); } 

Using:

 var upToTen = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; var evens = upToTen.Sample(2); var multiplesOfThree = upToTen.Sample(3); 
+8
source share

While not LINQ, you can also create an extension method with yield .

 public static IEnumerable<T> EverySecondObject<T>(this IEnumerable<T> list) { using (var enumerator = list.GetEnumerator()) { while (true) { if (!enumerator.MoveNext()) yield break; if (enumerator.MoveNext()) yield return enumerator.Current; else yield break; } } } 
0
source share

All Articles