Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing nested foreach with LINQ; modify and update a property deep within

Consider the requirement to change a data member on one or more properties of an object that is 5 or 6 levels deep.

There are sub-collections that need to be iterated through to get to the property that needs inspection & modification.

Here we're calling a method that cleans the street address of a Employee. Since we're changing data within the loops, the current implementation needs a for loop to prevent the exception:

Cannot assign to "someVariable" because it is a 'foreach iteration variable'

Here's the current algorithm (obfuscated) with nested foreach and a for.

foreach (var emp in company.internalData.Emps)
{
    foreach (var addr in emp.privateData.Addresses)
    {
        int numberAddresses = addr.Items.Length;

        for (int i = 0; i < numberAddresses; i++)
        {
            //transform this street address via a static method
            if (addr.Items[i].Type =="StreetAddress")
               addr.Items[i].Text = CleanStreetAddressLine(addr.Items[i].Text);
        }
    }
}

Question: Can this algorithm be reimplemented using LINQ? The requirement is for the original collection to have its data changed by that static method call.

Update: I was thinking/leaning in the direction of a jQuery/selector type solution. I didn't specifically word this question in that way. I realize that I was over-reaching on that idea (no side-effects). Thanks to everyone! If there is such a way to perform a jQuery-like selector, please let's see it!

like image 729
p.campbell Avatar asked Aug 26 '09 16:08

p.campbell


1 Answers

foreach(var item in company.internalData.Emps
                        .SelectMany(emp => emp.privateData.Addresses)
                        .SelectMany(addr => addr.Items)
                        .Where(addr => addr.Type == "StreetAddress"))
     item.Text = CleanStreetAddressLine(item.Text);
like image 131
mmx Avatar answered Oct 25 '22 17:10

mmx