tags:

views:

283

answers:

2

I am trying to achieve:

foreach (ScheduleItem s in ScheduleItems)
{
    foreach (IScheduleModule m in s.ScheduleModules)
    {
        yield return m;
    }
}

using LINQ aggregate and I do not understand why

return ScheduleItems.Aggregate(new Collection<IScheduleModule>(), (x, o) => x.Union(o.ScheduleModules) as Collection<IScheduleModule>);

returns null.

I have no issue using the nested foreach but my instinct was to use aggregate and I don't understand why it doesn't produce the same result.

Are there other approaches? What is best in terms of readability and performance?

+7  A: 

You should be using SelectMany for this:

ScheduleItems.SelectMany(s => s.ScheduleModules)

That exactly matches your initial nested foreach loop. It's also equivalent to this query expression:

from s in ScheduleItems
from m in s.ScheduleModules
select m

(although that will use a slightly different form of SelectMany).

As for why Aggregate isn't working: you're calling Union which returns an IEnumerable<T>, but then using as to try to convert it to Collection<T>. The result of Union won't be a Collection<T>, hence the result of the as operator is null.

Jon Skeet
Thanks Jon. This is exactly what I was looking to do and in a much tidier fashion.
Daniel Skinner
+2  A: 

Have you tried using SelectMany? Based on your question, that sounds like what you are looking for.

var results = ScheduleItems.SelectMany(si => si.ScheduleModules);
Scott Ivey
Thanks Scott, this is a much better solution than Aggregate (that's assuming it could be coerced into doing it)
Daniel Skinner