Настройка IEnumerable KeyValuePair

У меня есть 2 коллекции IEnumerable<KeyValuePair<TreeType, int>>:

  • _myObject.Trees — содержит все TreeTypes со значениями 0.
  • newTrees — может содержать любое количество TreeTypes с любым значением int.

Теперь то, что я хочу сделать, просто, но я пытался часами и не могу получить желаемых результатов. Я хочу вставить значения newTrees в коллекцию _myobject.Trees, чтобы не все значения _myObject.Trees были равны 0.

Ближайшее, что у меня есть, находится ниже. Я знаю, почему это не работает, но опять же, я просто не вижу решения.

    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;
            }
        }
    }

Был бы очень признателен за помощь, спасибо!


person user2439970    schedule 06.08.2013    source источник


Ответы (2)


Не могли бы вы попробовать что-то вроде следующего:

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);
}

Теперь вы зацикливаете только newTrees, а Where(...) находит соответствующий элемент(ы) в _myObject.Trees без явного зацикливания. Обратите внимание, что вызов First() предполагает, что любой ключ в newTrees уже существует в _myObject.Trees и что он существует только один раз.

Я надеюсь, что это помогает!

person Halvard    schedule 06.08.2013
comment
Большое спасибо за ваше время и помощь (и вам, и варокарбасу). Я буду тестировать это в течение часа (извините за задержку), но 2 коротких вопроса: я не вижу, как это на самом деле меняет коллекцию _myObject.Trees? Кроме того, коллекция _myObject.Trees доступна только для чтения. Мне нужно добавить сеттер или я могу обойтись без этого? Большое спасибо :) - person user2439970; 06.08.2013
comment
Только что протестировано, и все работает! Еще раз спасибо за помощь. Я ценю это :] - person user2439970; 06.08.2013

Хотя подход Халварда обеспечивает хорошее решение основной проблемы (+1 для него), он не указывает четко, как хранить значения в целевых позициях. Здесь у вас есть исправленная версия кода Халварда, основанная на наиболее типичном подходе: Dictionary (один из многочисленных постов, говорящих об этом):

 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;
person varocarbas    schedule 06.08.2013
comment
+1 Кажется более правильным изменить только такое значение, а не менять весь KeyValuePair, как я сделал в своем ответе, но оба решения должны давать один и тот же конечный результат (после вашего поста я внес незначительные изменения в свой код). - person Halvard; 06.08.2013
comment
@Халвард Спасибо. Для редактирования это более быстрый подход (тот, который рекомендуется везде). В любом случае, обратите внимание, что я изначально намеревался делать что-то по-другому (перебирать словарь), но ваш цикл явно лучше: комбинация обоих методов здесь является правильным решением :) - person varocarbas; 06.08.2013
comment
Спасибо за помощь. Это очень хороший способ решить мою проблему. - person user2439970; 06.08.2013
comment
@ user2439970 нет проблем. Но оригинальная петля была от Халварда, так что награду заслужил именно он: молодец. - person varocarbas; 06.08.2013