Цикл в словаре - PullRequest
       3

Цикл в словаре

3 голосов
/ 29 июня 2011

Я использую это:

foreach(KeyValuePair<String,String> entry in MyDic)
  {
      // do something with entry.Value or entry.Key

  }

Проблема в том, что я не могу изменить значение entry.Value или entry.Key

Мой вопрос заключается в том, как я могу изменитьзначение или ключ при циклическом просмотре словаря?И позволяет ли словарь дублировать ключ?И если да, как мы можем избежать?Спасибо

Ответы [ 5 ]

7 голосов
/ 29 июня 2011

Вы не можете изменить значение словарной записи при циклическом просмотре элементов в словаре, хотя вы можете изменить свойство значения, если это экземпляр ссылочного типа.

Например,

public class MyClass 
{
    public int SomeNumber { get; set;}
}

foreach(KeyValuePair<string, MyClass> entry in myDict)
{
    entry.Value.SomeNumber = 3; // is okay
    myDict[entry.Key] = new MyClass(); // is not okay
}

Попытка изменить словарь (или любую коллекцию) при циклическом просмотре его элементов приведет к InvalidOperationException о том, что коллекция была изменена.

Чтобы ответить на ваши конкретные вопросы,

Мой вопрос заключается в том, как я могу изменить значение или ключ при циклическом просмотре словаря?

Подход к обоим будет в значительной степени одинаковым. Вы можете либо перебрать копию словаря, как сказал Энтони Пенграм в его ответ , либо вы можете перебрать все элементы один раз, чтобы выяснить, какие из них нужно изменить, а затем снова перебрать список эти предметы:

List<string> keysToChange = new List<string>();
foreach(KeyValuePair<string, string> entry in myDict)
{
    if(...) // some check to see if it's an item you want to act on
    {
        keysToChange.Add(entry.Key);
    }
}

foreach(string key in keysToChange)
{
   myDict[key] = "new value";

   // or "rename" a key
   myDict["new key"] = myDict[key];
   myDict.Remove(key);
}

И позволяет ли словарь дублировать ключ? И если да, как мы можем избежать?

Словарь не допускает дублирование ключей. Если вам нужна коллекция из <string, string> пар, посмотрите NameValueCollection .

6 голосов
/ 29 июня 2011

Обновление словаря в цикле будет проблемой, так как вы не можете изменить словарь по мере его перечисления.Тем не менее, вы можете обойти это довольно легко, преобразовав словарь в список KeyValuePair<> объектов.Вы перечисляете этот список, а затем можете изменить словарь.

foreach (var pair in dictionary.ToList())
{
    // to update the value
    dictionary[pair.Key] = "Some New Value";

    // or to change the key => remove it and add something new
    dictionary.Remove(pair.Key);
    dictionary.Add("Some New Key", pair.Value);
}

Для второй части ключ в словаре должен быть уникальным.

0 голосов
/ 29 июня 2011

Вы не можете изменять ключи при перечислении их.

Один метод, который я использую для изменений в коллекции при перечислении их, заключается в том, что я делаю break; из цикла foreach, когда найдено совпадение и элемент изменен, и я перезапускаю все перечисление заново. Это один из способов справиться с этим ...

Нет, в словаре не может быть дубликатов ключей. Если вам нужно что-то, что будет сортировать по ключу и разрешать дублирование, вам следует использовать другую структуру данных.

0 голосов
/ 29 июня 2011

Вы можете сделать это как

for (int i = 0; i < MyDic.Count; i++)
{
    KeyValuePair<string, string> s = MyDic.ElementAt(i);
    MyDic.Remove(s.Key);
    MyDic.Add(s.Key, "NewValue");
}

И Словарь не допускает дублирования

0 голосов
/ 29 июня 2011

KeyValuePair ключ и значение только для чтения. Но вы можете изменить значение следующим образом:

dictionary[key].Value = newValue;

Но если вы хотите изменить ключ, вам придется удалить / добавить ключ.

И нет, словарь не позволяет дублировать ключи, он выдаст исключение ArgumentException.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...