Search code examples
wpfdatatemplatehierarchicaldatatemplate

How to group consecutive similar items of a collection?


Consider the following collection.

  • True
  • False
  • False
  • False
  • True
  • True
  • False
  • False

I want to display it in a structured way, say, in a TreeView. I want to be able to draw borders around entire groups and such.

  • True Group
    • True
  • False Group
    • False
    • False
    • False
  • True Group
    • True
    • True
  • False Group
    • False
    • False

How do I accomplish this with as little procedural code as possible?


Solution

  • This does what you're looking for and is generic:

    private static IEnumerable<IGrouping<int, T>> GroupConsecutive<T>(this IEnumerable<T> set, Func<T, T, bool> predicate)
    {
        var i = 0;
        var k = 0;
        var ranges = from e in set
                     let idx = ++i
                     let next = set.ElementAtOrDefault(idx)
                     let key = (predicate(e, next)) ? k : k++
                     group e by key into g
                     select g;
        return ranges;
    }
    

    Usage:

    var set = new List<bool>
                {
                    true,
                    false,
                    false,
                    false,
                    true,
                    true,
                    false,
                    false,
                };
    var groups = set.GroupConsecutive((b1, b2) => (b1 == b2));
    foreach (var g in groups)
    {
        Console.WriteLine(g.Key);
        foreach (var b in g)
            Console.WriteLine("\t{0}", b);
    }
    

    Output:

    0
            True
    1
            False
            False
            False
    2
            True
            True
    3
            False
            False