У меня есть внешняя петля, итерация по массиву подстрок, которые должны быть сопоставлены в словаре. Во внутреннем цикле я хочу перебрать словарь и удалить запись, чей ключ содержит подстроку. Как это сделать, не получив "Collection is modified Exception"?
foreach (string outerKey in new string[] { "PAYERADDR_PAYERNAME", "RECADDR_RECNAME", "PAYERADDR_ADDR", "RECADDR_ADDR" })
{
foreach (var item in _generalWorksheetData.Where(kvp => kvp.Value.Contains(outerKey)).ToList())
{
_generalWorksheetData.Remove(item.Key);
}
}
Вам нужна новая коллекция:
List<string> todelete = dictionary.Keys.Where(k => k.Contains("substring")).ToList();
todelete.ForEach(k => dictionary.Remove(k));
или с помощью foreach
:
foreach (string key in todelete)
dictionary.Remove(key); // safe to delete since it a different collection
Если Dictionary.Keys
реализовал IList
а не только ICollection
вы могли бы получить к нему доступ в обратном цикле для их удаления. Но поскольку индексатора нет, вы не можете.
List.ForEach
- не причина, по которой он работает, а потому, что я создаю новый список с ToList
. Как вы можете видеть теперь, вы можете использовать вместо него простой foreach
-loop.
Просто обновите свой внутренний foreach
следующим образом:
foreach (var item in _generalWorksheetData.Keys.Where(kvp => kvp.Contains(outerKey)).ToList())
{
_generalWorksheetData.Remove(item);
}
Обратите внимание, что методы расширения LINQ ToList
и ToArray
позволяют изменять коллекции.
List<string> sampleList = new List<string>();
sampleList.Add("1");
sampleList.Add("2");
sampleList.Add("3");
sampleList.Add("4");
sampleList.Add("5");
// Will not work
foreach (string item in sampleList)
{
sampleList.Remove(item);
}
// Will work
foreach (string item in sampleList.ToList())
{
sampleList.Remove(item);
}
Найдите совпадение и удалите записи, как показано ниже.
var keysWithMatchingValues = dictionary.Where(d => d.Key.Contains("xyz"))
.Select(kvp => kvp.Key).ToList();
foreach(var key in keysWithMatchingValues)
dictionary.Remove(key);
dic
является KeyValuPair
, но даже если вы используете Remove(dic.Key)
это также приводит к изменению исключения Collection, которое OP хочет предотвратить. То же самое происходит, если вы используете dictionary.Keys.Where(...)
Ключи. dictionary.Keys.Where(...)
вместо этого.
AFAIK, вы не можете. Однако вы можете сохранить эти пары в списке и удалить их в отдельном цикле с первого.
kvp.Value.Contains(outerKey)
;-) с вашим кодом, которым вы почти были. Это не работает, потому что вы выбираете элементы словаря здесьkvp
(KeyValuPair
), которые вы не должны изменять, если они являются частью цикла. Если бы вы взяли такие ключи, как.Select(kvp => kvp.Key).ToList()
это сработало бы; -]