2015-12-03 3 views
1

Я не могу понять, как добавить в словарь _collection новое значение от registeredValues, если ключ уже существует в _collection. Я хочу добавить к тому же ключу другой объект из registeredValues. Или, может быть, я делаю это неправильно?Словарь с ключом и значением

private readonly List<ThreePropertyHolder<string, string, string>> _registeredValues = new List<ThreePropertyHolder<string, string, string>>(); 

private Dictionary<string, List<object>> _collection = new Dictionary<string, List<object>>(); 

public Dictionary<string, List<object>> BlaBlaMethod() 
{ 
    foreach (var reValues in _registeredValues) 
    { 
     _collection.Add(reValues.Value2, new List<object>{reValues.Value3}); 
    } 
} 
+0

Ты знаком с кортежами ..? – MethodMan

+0

@MethodMan Нет, не совсем. – John

+1

Это встроенная версия ThreePropertyHolder, https://msdn.microsoft.com/en-us/library/dd387150(v=vs.110).aspx –

ответ

2

Вам необходимо выполнить другое действие, если оно добавляется или обновляется. Используйте TryGetValue, чтобы узнать, существует ли это значение, и обновите словарь, если это произойдет.

public Dictionary<string, List<object>> BlaBlaMethod() 
{ 
    foreach (var reValues in _registeredValues) 
    { 
     List<object> list; 
     if(!_collection.TryGetValue(reValues.Value2, out list)) 
     { 
      //The key was not there, add a new empty list to the dictionary. 
      list = new List<object>(); 
      _collection.Add(reValues.Value2, list); 
     } 

     //Now, if we are adding or updating, we just need to add on to our list. 
     list.Add(reValues.Value3); 
    } 
    return _collection; 
} 
+0

Master , выполнил эту работу. Спасибо. – John

0

Проверяя, существует ли ключ, вы можете выбрать, следует ли добавлять или обновлять запись. Основываясь на вашем образце, он должен работать следующим образом.

private readonly List<ThreePropertyHolder<string, string, string>> 
      _registeredValues = new List<ThreePropertyHolder<string, string, string>>(); 

private Dictionary<string, List<object>> _collection = new 
      Dictionary<string, List<object>>(); 

public Dictionary<string, List<object>> BlaBlaMethod() 
{ 
    foreach (var reValues in _registeredValues) 
    { 
     if (_collection.ContainsKey(reValues.Value2)) 
     { 
      _collection[reValues.Value2].Add(someOtherObject); 
     } 
     else 
     { 
      _collection.Add(
       reValues.Value2, 
       new List<object> { reValues.Value3 } 
      ); 
     } 
    } 

    return _collection; 
} 
+1

Это неправильная логика, вы переписываете список, он хочет добавить в список. Если вы только что переписываете его было бы дешевле просто '_collection [reValues.Value2] = новый список {reValues.Value3};' каждый раз, который будет перезаписываться, когда он существует, и добавлять, когда это не так. –

+1

Ваше обновление лучше, но оно по-прежнему неэффективно, не делайте «ContainsKey» и '_collection [reValues.Value2]', что вызывает два словарных поиска, если вы используете 'TryGetValue', вы можете сделать это одним поиском. –

1

версия LINQ в случае, если кто интересуется:

public Dictionary<string, List<object>> BlaBlaMethod() 
{ 
    _collection = _collection 
     .SelectMany(x => x.Value, (x, y) => new { x.Key, Value = y }) 
     .Concat(_registeredValues.Select(x => new { Key = x.Value2, Value = (object)x.Value3 })) 
     .GroupBy(x => x.Key, x => x.Value) 
     .ToDictionary(x => x.Key, x => new List<object>(x)); 
    return _collection; 
} 

Что это делает:

  1. Перерыв _collection в пар ключ/значение.
  2. Объединить то, что с _registeredValues преобразуется в пары ключ/значение.
  3. Группа по Key.
  4. Преобразуйте его обратно в словарь.

Это было бы немного проще, если _collection были определены как Dictionary<string, List<string>>, а не Dictionary<string, List<object>>. Это устранит необходимость отбрасывания до object, и вы можете просто сделать x.ToList() вместо new List<object>(x).

Смежные вопросы