Group 関数

シーケンス内の隣り合う要素のうち、同じ値のものを配列にまとめる関数 Group を作ってみました。

using System;
using System.Collections.Generic;
using System.Linq;

static class Iter {
    public static IEnumerable<T[]> Group<T>(IEnumerable<T> xs) {
        var ls = new List<T>();
        foreach (var x in xs) {
            if (ls.Count == 0 || ls[0].Equals(x)) {
                ls.Add(x);
            }
            else {
                yield return ls.ToArray();
                ls.Clear();
                ls.Add(x);
            }
        }
        if (ls.Count > 0) {
            yield return ls.ToArray();
        }
    }
}

class Program {
    static void Display<T>(IEnumerable<T[]> xxs) {
        var ls = new List<string>();
        foreach (var xs in xxs) {
            ls.Add(string.Format("[{0}]", string.Join(", ", xs)));
        }
        var s = string.Format("[{0}]", string.Join(", ", ls));
        Console.WriteLine(s);
    }

    static void Main() {
        Display(Iter.Group(new[] { 1 }));
        Display(Iter.Group(new[] { 1, 1 }));
        Display(Iter.Group(new int[0]));
        Display(Iter.Group(new[] { 1, 1, 0, 0, 1, 1, 1, 2, 2, 0, 0, 0 }));
        Display(Iter.Group(new[] { 1, 2, 3, 0, 0 }));
    }
}

実行結果です。

[[1]]
[[1, 1]]
[]
[[1, 1], [0, 0], [1, 1, 1], [2, 2], [0, 0, 0]]
[[1], [2], [3], [0, 0]]