Reputation: 1633
I need to iterate over three lists and process each combination. Order of the most outer and second level loop (list1
/ list2
) depends on some ordering rules.
Moreover I have some logic before and after the last (list3
) foreach loop.
ProcesPair
method uses all three items and depends on their order.
if (order == Order.Right)
{
foreach (var a in list1)
{
foreach (var b in list2)
{
DoSomethingBefore();
foreach (var c in list3)
{
ProcessPair(a, b, c);
}
DoSomethingAfter();
}
}
}
else if (order == Order.Down)
{
foreach (var b in list2)
{
foreach (var a in list1)
{
DoSomethingBefore();
foreach (var c in list3)
{
ProcessPair(a, b, c);
}
DoSomethingAfter();
}
}
}
Is it possible to make it somehow more elegant? I meen, how to reduce loops in code, something like Zip
function but each with each other.
Upvotes: 1
Views: 394
Reputation: 22866
Or just refactor the repeating code into a separate method:
void ProcessPairs(List<int> list1, List<int> list2, List<int> list3)
{
foreach (var a in list1)
foreach (var b in list2)
{
DoSomethingBefore();
foreach (var c in list3)
ProcessPair(a, b, c);
DoSomethingAfter();
}
}
and then
if (order == Order.Right)
ProcessPairs(list1, list2, list3);
else if (order == Order.Down)
ProcessPairs(list2, list1, list3);
Upvotes: 1
Reputation: 205569
Nested loops are indicator for LINQ SelectMany
. Hence the equivalent of the sample code could be like this:
var pairs =
order == Order.Right ? list1.SelectMany(a => list2, (a, b) => new { a, b }) ?
order == Order.Down ? list2.SelectMany(b => list1, (b, a) => new { a, b }) :
null;
if (pairs != null)
{
foreach (var pair in pairs)
{
DoSomethingBefore();
foreach (var c in list3)
{
ProcessPair(pair.a, pair.b, c);
}
DoSomethingAfter();
}
}
Upvotes: 2