If you want to learn all about LINQ, first go check out my series on TekPub and then come back here!
So, I blogged a while ago about the LINQ SelectMany operator. The LINQ SelectMany operator is one of the most useful, misunderstood, and underused operators in your LINQ repertoire. In my previous post I gave you a decent idea of what you can do with the LINQ SelectMany operator, but I’m not quite sure that I did a very good job at really showing you how it works. In this post, I want to give you a more visual explanation of the LINQ SelectMany operator, and what it can do for you.
As I said in my previous post about the SelectMany operator, MSDN describes it like this: “Projects each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence.” Again, once you are familiar with SelectMany, this is a great explanation, but it can still be a bit hard to visualize. So, let’s see…
1) it takes a sequence:
2) And then it iterates over each element in this sequence:
3) While it is iterating, it projects each element into an IEnumerable<T>:
4) And then flattens the resulting IEnumerables back into a single sequence:
Pretty easy to see now, right? The SelectMany operator allows us to produce a single sequence with 1 to n items for each item in the original sequence. It really allows us to sort-of multiply each item in a sequence, or at least project it into multiple items. If we did something like this with Select then we would end up producing a sequence with multiple sub-sequences, like this:
While this might be useful, it is not exactly what we want in this case. We want a single contiguous sequence which we can then operate on using other LINQ operators.
Remember that all you have to do is get a list from each item in a list. You can do this by accessing a list that is on each item, like this:
Or you could do it by generating a list, for example, what if each item was an integer, we could generate a range based on each number:
Pretty cool, and powerful. It also lets us chain calls to SelectMany, like this:
So basically, it let’s you continue to generate n number of sequences, and then combine them all back together. Since each call to SelectMany generates a single sequence, then you can call SelectMany on that resulting sequence and continue to do so as many times as you want.
While most of the operators in LINQ let you get one output element for each element you have in your sequence, or they let you filter out elements, but SelectMany is the only operator that lets you produce n output elements for each element in your input sequence. This fact opens up all kinds of possibilities with LINQ that otherwise wouldn’t be available to you. I hope this helps you out!