C# - Удаление Объектов из Словаря в цикле с условием продолжения

У меня есть это, и все, кажется, хорошо работает, но не уверенное почему и если его допустимое.

        Dictionary<string, List<string>> test = new Dictionary<string, List<string>>();

        while (test.Count > 0)
        {
            var obj = test.Last();
            MyMethod(obj);
            test.Remove(obj.Key);
        }

Обновление: Спасибо за ответы я обновил свой код для объяснения, почему я не делаю Словаря. Ясный ();

5
задан Jon 29 June 2010 в 18:41
поделиться

9 ответов

Нет ничего плохого в таком изменении типа коллекции в цикле while. Проблемы возникают, когда вы изменяете коллекцию во время блока foreach . Или, в более общем смысле, используйте IEnumerator после того, как основная коллекция будет изменена.

Хотя в этом примере было бы намного проще просто вызвать test.Clear () :)

10
ответ дан 18 December 2019 в 07:53
поделиться

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

Было бы немного быстрее получить список всех ключей и обрабатывать записи по ключу вместо того, чтобы пересчитывать снова и снова ...

EG:

var keys = test.Keys.OrderByDescending(o => o).ToList();

foreach (var key in keys)
{
    var obj = test[key];
    MyMethod(obj);
    test.Remove(key);
}

Диктонарии работают быстро, когда к ним обращаются по их значению ключа . Last () работает медленнее, и подсчет не требуется - вы можете получить список всех (уникальных) ключей.

8
ответ дан 18 December 2019 в 07:53
поделиться

Это работает, потому что счетчик будет обновляться каждый раз, когда вы удаляете объект. Скажем, count равно 3, test.Remove вернет счет в 2 и так далее, пока счетчик не станет 0, тогда вы выйдете из цикла

1
ответ дан 18 December 2019 в 07:53
поделиться

Все, что вы делаете, это берете последний элемент в коллекции и удаляете его, пока в Словаре не останется больше элементов.

Ничего необычного, и нет никаких причин, по которым это не должно работать (если вы хотите очистить коллекцию).

0
ответ дан 18 December 2019 в 07:53
поделиться

Это работает, прекрасно, поскольку вы не перебираете словарь при удалении элементов. Каждый раз, когда проверяешь test.Count, как будто проверяет с нуля.

При этом приведенный выше код можно было бы написать намного проще и эффективнее:

test.Clear();
1
ответ дан 18 December 2019 в 07:53
поделиться

Да, это должно быть допустимым, но почему бы и нет просто вызовите Dictionary.Clear () ?

0
ответ дан 18 December 2019 в 07:53
поделиться

Кажется, что это сработает, но это выглядит чрезвычайно дорого. Это было бы проблемой, если бы вы итерировали его с помощью цикла foreach (вы не можете редактировать коллекции во время итерации).

Dictionary.Clear() должен сделать трюк (но вы, вероятно, уже знаете это).

0
ответ дан 18 December 2019 в 07:53
поделиться

Несмотря на ваше обновление, вы, вероятно, все еще можете использовать clear ...

foreach(var item in test) {
  MyMethod(item);
}
test.Clear()

Ваш вызов .Last () будет крайне неэффективным для большого словаря и не будет гарантировать какой-либо конкретный порядок обработки независимо от ( Словарь представляет собой неупорядоченный сборник)

0
ответ дан 18 December 2019 в 07:53
поделиться

Итак, вы просто пытаетесь очистить словарь, верно? Не могли бы вы просто сделать следующее?

Dictionary<string, List<string>> test = new Dictionary<string, List<string>>();
        test.Clear(); 
0
ответ дан 18 December 2019 в 07:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: