Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ Aggregate vs. nested foreach

Tags:

linq

aggregate

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?

like image 496
djskinner Avatar asked Dec 14 '22 02:12

djskinner


2 Answers

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.

like image 120
Jon Skeet Avatar answered Dec 15 '22 17:12

Jon Skeet


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

var results = ScheduleItems.SelectMany(si => si.ScheduleModules);
like image 23
Scott Ivey Avatar answered Dec 15 '22 15:12

Scott Ivey