Wednesday, March 2, 2011

Example code for SplitUp(), on infinite sequence! ;-)

I've received some positive reactions to my previous post, in which I gave source code of a lazy implementation of a SplitUp() function that could be used for paging an IEnumerable<T>.

However, I also got comments that example code on how you could use this would be nice. I had been thinking about that - also to show off exactly how the SplitUp() code is lazy and what actually happens if you use it - but decided to leave it out. That was mainly because I myself already knew; it just wasn't a goal of that previous blog post for me. Personally I'm not that much of a "need to see it work in an example" kind of guy, you know? Plus, blog posts take a bit of time. ;-)

Having said that, I can now give you this example, which should be self-explanatory if you run the following code in a console app project that includes the source from the previous blog code as well. Hope you enjoy it; as always all comments are welcome!

namespace SplitUpExample
{
  using System;
  using System.Linq;
  using System.Collections.Generic;
  using peSHIr.Utilities;

  class Program
  {
    static bool TraceDataCreation;
        
    static Action<string> println = text => Console.WriteLine(text);
    static Action<string> print = text => Console.Write(text);
    static Action newline = () => Console.WriteLine();

    static void Main(string[] args)
    {
      newline();
      println("* How can SplitUp() be used for paging");
      TraceDataCreation = false;
            
      var allData = TestData(64);
      var pagedData = allData.SplitUp(7);
      foreach (var page in pagedData)
      {
        print("Page:");
        foreach (int i in page)
        {
           print(" ");
           print(i.ToString());
        }
        newline();
      }

      newline();
      println("* And is it really lazy?");
      TraceDataCreation = true;
            
      println("Calling SplitUp() on infinite sequence now");
      var pagedInfinity = TestData().SplitUp(4);

      println("Retrieving first page now");
      var page1 = pagedInfinity.ElementAt(0);
            
      println("Retrieving third page now");
      var page3 = pagedInfinity.ElementAt(2);
            
      Action<string,int,int> results = (text,sum,count)
        => Console.WriteLine("{0}: {1}, {2}", text, sum, count);

      println("Showing results:");
      results("First page", page1.Sum(), page1.Count());
      results("Third page", page3.Sum(), page3.Count());
      println("So yes, SplitUp() is lazy like LINQ! ;-)");

#if DEBUG
      newline();
      println("(Key to quit)");
      Console.ReadKey();
#endif
    }

    static IEnumerable<int> TestData(int n)
    {
      return TestData().Take(n);
    }

    static IEnumerable<int> TestData()
    {
      // WARNING: this returns an infinite sequence!
      // Or at least: until int overflows... ;-)
      int i = 0;
      while (true)
      {
        if (TraceDataCreation)
          Console.WriteLine("Yielding {0}", i);
        yield return i++;
      }
    }

  }

}

2 comments:

  1. Excellent! Because I *am* the kind of guy that *does* needs an example to see it work (hums "This is how we do it")

    ReplyDelete
  2. (Did a quick tiny edit, to make sure source was narrow enough no to need a horizontal scrollbar any more.)

    ReplyDelete