Is there an easier way to use Rx's GroupBy operator? I'm just playing with the concept of GroupBy inside Rx. So, I wondered how hard it would be to write a console application that continuously reads lines, groups them by similar words and just prints out the word among the current count of how often the word was written before. It really was a breeze to do that but I wonder if my attempt could be rewritten in a more elegant way. Especially if I can get rid of the nested Subscribes.

Here is what I have:

static void Main(string[] args)
{
    var subject = new Subject&lt;string&gt;();

    var my = subject.GroupBy(x =&gt; x);

    my.Subscribe(x =&gt; x.Scan(new { Chars = string.Empty, Count = 0},
                                 (a, chars) =&gt; new { Chars = chars, Count = a.Count + 1})
      .Subscribe(result =&gt; Console.WriteLine("You typed {0} {1} times", result.Chars, 
                 result.Count)));

    while (true)
    {
        subject.OnNext(Console.ReadLine());
    }
}




Result

test
you typed test 1 times
test
you typed test 2 times
hallo
you typed test 1 times
test
you typed test 3 times
...
You could use also use a counter provider per grouping observable, in the form of zipping a large stream of integers, like so:

static void Main(string[] args)
{
    var input = GetConsoleLines().ToObservable().TakeWhile(line =&gt; !string.IsNullOrEmpty(line));
    input.GroupBy(word =&gt; word)
         .SelectMany(grouping =&gt; grouping.Zip(Observable.Range(1, int.MaxValue), (s, i) =&gt; new Tuple&lt;string, int&gt;(s, i)))
         .Subscribe(r =&gt; Console.WriteLine($"you typed {r.Item1} {r.Item2} times"));
}

public static IEnumerable&lt;string&gt; GetConsoleLines()
{
    while(true)
        yield return Console.ReadLine();
}