Reputation: 13
Basically I have a method that is passed a list of custom objects. I'm using C#. Each of these contains a name and another list of other custom objects, I'll call these subObjects. These each have a name and a list of strings. I need to loop through all the strings, but keep track of the names of the parent object and subject for error logging purposes. Is there a cleaner, nicer way to do this than nesting foreachs?
foreach (var obj in listOfObjects)
{
foreach (var subObj in obj.subObjects)
{
foreach (var aString in subObj.strings)
{
if (some condition applies)
{
//log error that includes obj, subObj, and subSubObj names, and aString.
}
}
}
}
Upvotes: 1
Views: 1649
Reputation: 25
The way I do it :
foreach (YourClass something in YourObject.SelectMany(x => x.Nested).SelectMany(x => x.MoreNesting)) {
// Do Stuff Here
}
Probably not the best way to do it or whatever, it's just the clearest way for me, while avoiding the triple nesting look I don't quite like.
Upvotes: -1
Reputation: 633
Adding to MarcinJuraszek answer, if linq to objects is preferred...
var errors = listOfObjects
.SelectMany(obj => obj.subObjects
.SelectMany(subObj => subObj.strings
.Where(r => /* your condition */)
.Select(aString => new { obj, subObj, aString })));
But there's nothing wrong with the code you posted. Clearly, yours is easier to follow at a quick glance.
Upvotes: 0
Reputation: 125620
You can write a LINQ query to get all error cases
var errors = from obj in listOfObjects
from subObj in obj.subObjects
from aString in subObj.strings
where /* your condition */
select new { obj, subObj, aString };
and than iterate over them only:
foreach(var errorCase in errors)
{
// log your error
}
or get the first one:
var error = errors.FirstOrDefault();
depending on your needs.
Upvotes: 3