locked
Escape outer variable trap in two nested foreach with Dictionary<T> RRS feed

  • Question

  • I have two objects that I initialize like this:
    var series = new Dictionary<string,Dictionary<string,int>>()
    {
       {"0", new Dictionary<string, int>() },
       {"1", new Dictionary<string, int>() },
       {"2", new Dictionary<string, int>() }
    }
    
    var periodValues = new Dictionary<string,int>();
    {
       {"Jan", 0 },
       {"Feb", 0 },
       {"Mar", 0 }
    }
    

    Then I have another object with filled values:

     var target = new Dictionary<string,Dictionary<string,int>>()
     {
           { "0", 
             new Dictionary<string, int>()
             {
                {"Jan", 12 },
                {"Mar", 22 }
             } 
           },
           { "1", 
             new Dictionary<string, int>()
             {
                {"Mar", 37 }
             } 
           },
           { "2", 
             new Dictionary<string, int>()
             {
                {"Jan", 4 },
                {"Feb", 48 },
                {"Mar", 22 }
             } 
           }
     }
    

    series and target have always the same Key, while target[key].Keys (with key of type string) for any key can be a subset (at the most the same) of periodValues.Keys.

    Now I want to fill series.Values according to the keys in periodValues.Keys but with the values of target[key].Value. Therefore:

    foreach (var numberValue in target.Keys)
    {
        foreach (var period in target[numberValue].Keys)
        {
            periodValues[period] = target[numberValue][period];
        }
        series[numberValue] = periodValues;
    }
    

    But I fall in the outer variable trap...that means all series[key] for any series.Keys are equal to the last periodValues. I tried many solutions to escape the outer variable trap according to this article with no luck. Anybody knows a solution or maybe a better approach?

    Thursday, December 13, 2012 4:08 PM

Answers

  • You need a new periodValues dictionary for each iteration of the loop. Move the periodValues variable declaration and initialization from outside the love to inside the loop:
    foreach (var numberValue in target.Keys)
    {
        var periodValues = new Dictionary<string, int>()
        {
            {"Jan", 0 },
            {"Feb", 0 },
            {"Mar", 0 }
        };
        foreach (var period in target[numberValue].Keys)
        {
            periodValues[period] = target[numberValue][period];
        }
        series[numberValue] = periodValues;
    }


    • Edited by Louis.fr Thursday, December 13, 2012 4:44 PM
    • Marked as answer by Trinakriae Friday, December 14, 2012 10:11 AM
    Thursday, December 13, 2012 4:43 PM