2

I have 2 IEnumerable<KeyValuePair<TreeType, int>> collections:

  • _myObject.Trees - contains all the TreeTypes with values of 0.
  • newTrees - can contain any number of TreeTypes with any int value.

Now what I want to do is simple but I've been trying for hours and can't quite get the desired results. I want to insert the newTrees values into the _myobject.Trees collection, so that the _myObject.Trees values won't all be 0.

The closest I've got is below. I know why this doesn't work, but again, I just can't see the solution.

    foreach (var tree in _myObject.Trees)
    {
        foreach (var newTree in newTrees)
        {
            if (tree.Key == newTree.Key)
            {
                _myObject.Trees[tree] =
                    new KeyValuePair<TreeType, int>(newTree.Key, newTree.Value);
                break;
            }
        }
    }

Would really appreciate the help, thanks!

user2439970
  • 129
  • 1
  • 11

2 Answers2

1

Could you try something like the following:

foreach (var tree in newTrees)
{
     var keyValuePair = _myObject.Trees.Where(s => s.Key == tree.Key).First();
     keyValuePair = new KeyValuePair<Tree, int>(tree.Key, tree.Value);
}

Now you are looping only the newTrees and the Where(...) finds the corresponding element(s) in _myObject.Trees without explicitly looping. Note that the call to First() assumes that any key in newTrees already exists in _myObject.Trees and that it exists only once.

I hope it helps!

Halvard
  • 3,891
  • 6
  • 39
  • 51
  • Thank you very much for your time and assistance (both you and varocarbas). I will be testing this within the hour (sorry for the delay), but 2 quick questions: I don't see how this actually changes the _myObject.Trees collection? Also, the _myObject.Trees collection is read-only..do I need to add a setter or can I get away without doing this? Thank you very much :) – user2439970 Aug 06 '13 at 15:37
  • Just tested and all works a treat! Again, thank you for the help. I appreciate it :] – user2439970 Aug 06 '13 at 17:26
1

Although the Halvard approach provides a good solution for the main problem (+1 for him), it does not state clearly how to store the values in the target positions. Here you have a corrected version of Halvard's code relying on the most typical approach: a Dictionary (one of the multiple posts talking about this):

 Dictionary<TreeType, int> dict = _myObject.Trees.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
 foreach (var tree in newTrees)
 {
     var keyValuePair = _myObject.Trees.Where(s => s.Key == tree.Key);
     if (keyValuePair.Count() > 0)
     {
         dict[keyValuePair.First().Key] = tree.Value; //Value of the given tree associated with the current Key of _myObject.Trees
     }
 }

_myObject.Trees = dict;
Community
  • 1
  • 1
varocarbas
  • 12,354
  • 4
  • 26
  • 37
  • +1 It seems more correct to only change the value like this rather than change the whole KeyValuePair like I did in my reply, but both solutions should give the same end result (I did a minor edit to my code after your post). – Halvard Aug 06 '13 at 14:35
  • @Halvard Thanks. For editing, it is a quicker approach (the one recommended everywhere). In any case, note that my original intention was doing things differently (iterating through the dictionary), but your loop is clearly better: a combination of both methods is the right solution here :) – varocarbas Aug 06 '13 at 14:39
  • Thanks for the help. This is a very nice way of solving my problem. – user2439970 Aug 06 '13 at 17:27
  • @user2439970 no problem. But the original loop was from Halvard, so he is the one deserving the award: well done. – varocarbas Aug 06 '13 at 17:32