Take the 2-minute tour ×

In Ruby there is an each_cons on Enumerable. It works like this

(1..5).each_cons(3) {|n| p n}

[1, 2, 3]
[2, 3, 4]
[3, 4, 5]

I would like to do this in C#. LINQ would be nice.

The following does something similar but it loops one to many and it's also hardcoded to return only two elements

var cons = ints.Select((o, i) =>
            new int[]{ ints[i], i == ints.Length - 1 ? 0 : ints[i + 1] });

It would be nice if it could be created as an iterator over the original array instead of having to create a lot of arrays.

share|improve this question

3 Answers 3

up vote 9 down vote accepted

Try the following

var ints = Enumerable.Range(1, 3).Select(x => Enumerable.Range(x, 3));

This will return an IEnumerable<IEnumerable<int>> with the specified values. You can add the .ToArray expression at any point to get it into an array if that's the intent (can't tell if that's whatthe [] mean in ruby)

share|improve this answer
+1 I use statements like this all the time –  Adam Ralph Jan 11 '11 at 17:24
Nice and I don't actually need to do it over unordered ranges/arrays. Not right now anyway. –  Jonas Elfström Jan 11 '11 at 17:25
Awesome for int; no good for generic "n elements". –  Jay Jan 11 '11 at 19:14
@Jay: Actually is good for generic too. You just need something that generates a T from an int, then with a simple Select the job is done. –  digEmAll Jan 11 '11 at 22:57

You can create an extension method that achieves it in this way:

    public static IEnumerable<IEnumerable<T>> each_cons<T>(this IEnumerable<T> enumerable, int length)
        for (int i = 0; i < enumerable.Count() - length + 1; i++)
            yield return enumerable.Skip(i).Take(length);

Consume it:

var ints = Enumerable.Range(1, 7).each_cons(3);
share|improve this answer
If the enumerable is some kind of linked list, wouldn't the Skip(i) get slower by each iteration then? –  Jonas Elfström Jan 11 '11 at 17:46
@Jonas This is actually extremely fast -- between 150 and 250 times faster than the head/tail implementation you'd been using in the previous extension method you posted, and using a LinkedList<int> actually makes it significantly faster. –  Jay Jan 11 '11 at 18:59
How did you measure that? I did some simple StopWatch tests with lists of 100000 numbers and though mine was slower it was only 12ms against 15ms. –  Jonas Elfström Jan 11 '11 at 22:55
@Jonas Don't forget to call ToList() or ToArray() on both the inner and outer IEnumerable<T>. Using the yield keyword means that execution is deferred -- there is no enumeration until the values are requested/used, but you can force evaluation by creating a list or array. –  Jay Jan 12 '11 at 0:51
I thought I did that but I did not. Now that I did I see the HUGE speed difference. –  Jonas Elfström Jan 12 '11 at 8:27

Here's a generic extension method that turned out to be way to complicated for my current use case but it seems to work.

static class EnumerableExtension
    public static IEnumerable<IEnumerable<T>> EachCons<T>(this IEnumerable<T> sequence, int cons)
        for (IEnumerable<T> head = sequence.Take(cons), tail = sequence.Skip(1);
             head.Count() == cons; head = tail.Take(cons), tail = tail.Skip(1))
             yield return head;

Use Jay's implementation instead. It's MUCH faster. I just left this one here because it's mentioned in Jay's answer.

share|improve this answer

Your Answer


