Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate and return array of consecutive n elements

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 ints = new int[] { 1, 2, 3, 4, 5, 6, 7 };
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.

like image 877
Jonas Elfström Avatar asked Jan 11 '11 17:01

Jonas Elfström


2 Answers

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)

like image 114
JaredPar Avatar answered Nov 15 '22 11:11

JaredPar


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);
like image 6
Jay Avatar answered Nov 15 '22 10:11

Jay