I have a method with a nested foreach
collection (iterate a set of objects and then look inside each object). I saw in a book a good pattern to make this much more elegant but cannot remember/find the code example. How else could I make this more tidy?
The code is just a typical nested foreach
statement so I have not provided a code sample.
I'd suggest creating a Dictionary out of the second thing you loop through. Then inside the foreach just use your Dictionary as a lookup for the value you want. I guess you mean a queue or stack instead of a dictionary. Please look up graph traversal algorithm and then update your answer.
The nesting operator: %:% I call this the nesting operator because it is used to create nested foreach loops. Like the %do% and %dopar% operators, it is a binary operator, but it operates on two foreach objects. It also returns a foreach object, which is essentially a special merger of its operands.
The obvious solution is to flatten into methods.
Old:
void SubmitOrders()
{
var orders = GetOrders();
foreach (Order o in orders)
{
foreach (OrderDetail d in o.Details)
{
// Blah...
}
}
}
New:
void SubmitOrders()
{
var orders = GetOrders()
foreach (Order o in orders)
{
SubmitOrder(o);
}
}
void SubmitOrder(Order order)
{
foreach (OrderDetail d in order.Details)
{
// Blah...
}
}
Other answers here seem to be focused on Linq, and I would agree that if your loops have no side-effects (i.e. you are just trying to extract some information from the innermost loop), then you can probably rewrite the entire thing using one or two simple Linq statements. If side-effects are involved, then just follow the time-tested practice of subroutines.
You're going to have to be more specific about what you mean regarding "more elegant", as IMO there's nothing particularly inelegant about a nested foreach
.
That being said, the LINQ extension methods in .NET 3.5 and above can help out (specifically SelectMany
).
public class Foo
{
public List<string> Strings { get; set; }
}
...
List<Foo> foos = new List<Foo>();
foreach(string str in foos.SelectMany(f => f.Strings))
{
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With