I have added a few more methods to Dizzy recently, namely Concatenate (which I am considering renaming to Chain), Reverse, and Partition. None of these methods were particularly difficult to implement, but they are interesting nonetheless. The most interesting of them is Partition, which simply splits up a list using a Predicate delegate. In case you are not in the know, a Predicate delegate is simply a delegate that takes some value and returns a boolean. Its signature looks like this:
public static Pair<IEnumerable<T>>
Partition<T>(this IEnumerable<T> list, Predicate<T> predicate)
So, you take a list and then call something like:
var nums = new List<int> {2, 5, 6, 9, 4, 10, 1};
Pair<IEnumerable<int>> splitNums = nums.Partition(n => n > 5);
If you had a list of integers, this would take your list and split it into two lists. One that has all numbers greater than 5 and the other that has numbers less than 5. Pretty easy stuff, nothing ground breaking.
The slightly more interesting part is in how we are returning two lists. We have declared a new class called Pair, which is named the same as the Pair class already in .net, only it is generic. For my purposes I only used a single generic argument, and this was so that I could implement IEnumerable<T> on the Pair class. The reason why this is interesting is that if I wanted to split a list into two, and I wanted to do further processing on it without IEnumerable then I would have to assign the result to an intermediate variable. I wouldn’t be able to iterate over the result of the list. The Pair class looks like this:
public class Pair<T> : IEnumerable<T>
{
public T First { get; set; }
public T Second { get; set; }
public Pair()
{
}
public Pair(T first, T second)
{
this.First = first;
this.Second = second;
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<T>)this).GetEnumerator();
}
public IEnumerator<T> GetEnumerator()
{
yield return First;
yield return Second;
}
}
What this allows me to do is this:
nums.Partition(n => n > 5).ForEach(l => l.ForEach(Console.WriteLine));
Here, I am taking my list of numbers and I am splitting it into numbers below and above 5. Then I am feeding the result into ForEach which will loop through both lists, and then pass those lists into ForEach to loop through each integer. This will output this (notice all of the integers that match the predicate get pushed to the front):
In the future I plan on implementing a method in Dizzy that will make doing these sub-iterations a bit easier.
You may be looking at this and saying “What good does it do to split a list into two only to put it back together?” Well, first of all it could be used to reorder things to the front of a list, secondly, I have a few ideas for other methods that I can implement to operate on the Pair<T>. One idea is for a “Fork” method that would take both lists and allow you to do separate processing on each list.
Hopefully this method will help you out, or at least give you a few ideas! If you haven’t already, check out Dizzy!
Loved the article? Hated it? Didn’t even read it?
We’d love to hear from you.
Hey Justin,
I just went to the Dizzy project page and I see that there are no releases. Could you do a source code release?
Thanks!
Luke
I haven’t made any releases, but if you go to the "source" tab there is download links on each of the revisions. Just click it on the top revision and it will download a zip file of all the source!