Итерация и возврат массива последовательных n элементов - PullRequest
6 голосов
/ 11 января 2011

В Ruby есть each_cons на Enumerable . Это работает так

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

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

Я хотел бы сделать это в C #. LINQ было бы неплохо.

Следующее делает нечто похожее, но оно повторяет один ко многим, а также жестко закодировано, чтобы вернуть только два элемента

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

Было бы неплохо, если бы он мог быть создан как итератор над исходным массивом вместо того, чтобы создавать много массивов.

Ответы [ 3 ]

9 голосов
/ 11 января 2011

Попробуйте следующее

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

Это вернет IEnumerable<IEnumerable<int>> с указанными значениями.Вы можете добавить выражение .ToArray в любой момент, чтобы получить его в массив, если это является намерением (не могу сказать, означает ли это [] в рубине)

6 голосов
/ 11 января 2011

Вы можете создать метод расширения, который достигает его следующим образом:

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

Потребь это:

var ints = Enumerable.Range(1, 7).each_cons(3);
0 голосов
/ 11 января 2011

Вот общий метод расширения, который оказался сложным для моего текущего варианта использования, но, похоже, он работает.

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

Вместо этого используйте реализацию Джея. Это НАМНОГО быстрее. Я просто оставил это здесь, потому что это упоминается в ответе Джея.

...