Is it possible to create some IGrouping object

If you really wanted to create your own IGrouping<TKey, TElement>, it is a simple interface to implement:

public class Grouping<TKey, TElement> : List<TElement>, IGrouping<TKey, TElement>
{
    public Grouping(TKey key) : base() => Key = key;
    public Grouping(TKey key, int capacity) : base(capacity) => Key = key;
    public Grouping(TKey key, IEnumerable<TElement> collection)
        : base(collection) => Key = key;
    public TKey Key { get; }
}

Note: you shouldn’t try to allow the Key to be settable, mainly because the key should be managed by the collection that this Grouping is contained within.

This class inherits from List<T> and implements the IGrouping interface. Aside of the requirement of being an IEnumerable and IEnumerable<TElement> (which List<T> satisfies) the only property to implement is Key.

You could create List of these groups from scratch:

var groups = new List<Grouping<string, string>>();
groups.Add(new Grouping<string,string>("a", new string [] { "apple" }));
groups.Add(new Grouping<string,string>("p", new string [] { "peach", "pear" }));
groups.Add(new Grouping<string,string>("o", new string [] { "orange" }));

// inline variant:
groups = new List<Grouping<string, string>>
{
    new Grouping<string, string>("a", new string[] { "apple" }),
    new Grouping<string, string>("p", new string[] { "peach", "pear" }),
    new Grouping<string, string>("o", new string[] { "orange" }),
};

Or you could use this structure to append new groups to the results of a previous Linq GroupBy expression that has been evaluated into a list:

var strings = new string [] { "apple", "peach", "pear" };
var groups = strings.GroupBy(x => x.First().ToString()).ToList();
…
// Inject a new item to the list, without having to re-query
groups.Add(new Grouping<string,string>("o", new string [] { "orange" }));

If you need to add Items to the groups resolved from an IGrouping expression you can cast the Linq results into a List of Grouping:

var strings = new string [] { "apple", "peach", "orange" };
var groupExpression = strings.GroupBy(x => x.First().ToString());
var editableGroups = groupExpression.Select(x => new Grouping<string,string>(x.Key, x)).ToList();
…
// Add "pear" to the "p" list, with a check that the group exits first.
var pGroup = editableGroups.FirstOrDefault(x => x.Key == "p");
if (pGroup == null)
    editableGroups.Add(new Grouping<string, string>("p", new string[] { "pear" }));
else
    pGroup.Add("pear");

Leave a Comment