Reputation: 903
In the following code I'm using 3 foreach statements. I'm just looking to populate a list when a list of items matches another but the ones that don't match also have to be added. So I was wondering if there is an easier way to do the following.
List<T> ds = new List<T>(); //is populated
foreach (var b in template.Bs)
{
List<BD> tempList = new List<BD>();
foreach (BD bd in b.BDs)
{
Boolean found = false;
foreach (DV dv in items)
{
if (bd.C == dv.C)
{
found = true;
tempList.Add(new BD ()
{
//populating
});
}
}
if (!found)
tempList.Add(new BD()
{
//populating
});
}
}
Upvotes: 0
Views: 313
Reputation: 77610
The relationship between ds
and tempList
is not clear, but it looks to me like your inner loops are really a left outer join:
List<T> ds = new List<T>(); //is populated
foreach (var b in template.Bs)
{
var newBDs = from bd in b.BDs
join dv in items on bd.C equals dv.C into j
from dv in j.DefaultIfEmpty()
select dv == null ? NoMatch(bd) : Match(bd, dv);
List<BD> tempList = newBDs.ToList();
// Do something with tempList
}
For each b
in template.Bs
, we're matching bd
's from b.BDs
with dv
's in items
. We then use DefaultIfEmpty()
to put null
in dv
if there was no match, which we then use to determine which projection method to call: NoMatch()
would create a new BD
based on the unmatched bd
, and Match()
would create a new BD
based on the matched bd
and dv
.
That whole query is represented by newBDs
, which will be IEnumerable<BD>
. We can then buffer that sequence into tempList
or do something else useful with it.
Upvotes: 6