C# Generic conversion/grouping tricks
Note: none of this is new, it is just new to me.
I used to love C, for its speed and flexibility. I learned to love C# for its exception handling features. To me, the real killer feature of C# 2+ is the generics. It is undeniably easy to understand and makes my work profoundly easier.
One of the problems I have been having with generics is when I need a List<K> when I really need a List<T>. I stumbled upon the generic Converter class (finally) which makes life much easier for these scenarios.
This code builds a collection of floats and uses a delegate to convert it in to a collection of ints

Cool, but what if it is not a true one-to-one conversion between the source type and the target type? I mean, what if a bunch of Ks convert in to a common T? How about a grouping method?
This code takes in a collection of the source type, a converter, and returns a dictionary of the target type as keys, and collections of the source type as grouped values.
Now this generic GroupBy method is going to be very handy in the future, especially since the delegate will dictate the behavior of the converting/grouping functionality.
Lets take this one step further: what if every K converts in to a collection of different Ts? Then we will need a "Fan Out" function (very handy for genetic algorithm processing, it turns out):
I used to love C, for its speed and flexibility. I learned to love C# for its exception handling features. To me, the real killer feature of C# 2+ is the generics. It is undeniably easy to understand and makes my work profoundly easier.
One of the problems I have been having with generics is when I need a List<K> when I really need a List<T>. I stumbled upon the generic Converter class (finally) which makes life much easier for these scenarios.
This code builds a collection of floats and uses a delegate to convert it in to a collection of ints
public void Testx()
{
List<float> _floats = new List<float>();
_floats.Add(1f);
_floats.Add(11.5f);
_floats.Add(12f);
_floats.Add(1.1f);
_floats.Add(55f);
_floats.Add(124f);
_floats.Add(127.2f);
_floats.Add(6222f);
List<int> _ints = _floats.ConvertAll(ConvertFloatToInt);
}
public static int ConvertFloatToInt(float x)
{
return Convert.ToInt32(x);
}

Cool, but what if it is not a true one-to-one conversion between the source type and the target type? I mean, what if a bunch of Ks convert in to a common T? How about a grouping method?
This code takes in a collection of the source type, a converter, and returns a dictionary of the target type as keys, and collections of the source type as grouped values.
public static IDictionary<T, ICollection<K>> GroupBy<K,T >(ICollection<K> collection, Converter<K, T> converter)
{
Dictionary<T, ICollection<K>> _dictionary = new Dictionary<T, ICollection<K>>();
foreach (K k in collection)
{
T key = converter(k);
if (_dictionary.ContainsKey(key) == false)
{
_dictionary[key] = new List<K>();
}
_dictionary[key].Add(k);
}
return _dictionary;
}
public static int ConvertFloatToMod10Int(float x)
{
return Convert.ToInt32(x % 10);
}
[Test]
public void Testx()
{
List<float> _floats = new List<float>();
_floats.Add(1f);
_floats.Add(11.5f);
_floats.Add(12f);
_floats.Add(1.1f);
_floats.Add(55f);
_floats.Add(124f);
_floats.Add(127.2f);
_floats.Add(6222f);
Converter<float, int> _converter = new Converter<float, int>(ConvertFloatToMod10Int);
IDictionary<int, ICollection<float>> _dictionary = GroupBy(_floats, _converter);
}
Now this generic GroupBy method is going to be very handy in the future, especially since the delegate will dictate the behavior of the converting/grouping functionality.
Lets take this one step further: what if every K converts in to a collection of different Ts? Then we will need a "Fan Out" function (very handy for genetic algorithm processing, it turns out):
public static IDictionary<K, ICollection<T>> FanOut<K, T>(ICollection<K> collection, Converter<K, ICollection<T>> converter)
{
IDictionary<K, ICollection<T>> _dictionary = new Dictionary<K, ICollection<T>>();
foreach (K _k in collection)
{
ICollection<T> fan = converter(_k);
_dictionary.Add(_k,fan);
}
return _dictionary;
}
Labels: C#


2 Comments:
Why not use LINQ for this?
var _dictionary = _floats.GroupBy(f => Convert.ToInt32(f % 10)).ToDictionary(g => g.Key);
this was written when linq was still in beta
Post a Comment
<< Home