2015-01-12 21 views
1

我有一个外部循环迭代在字典中匹配的子字符串数组。在内部循环中,我想迭代字典并删除其中包含子字符串的条目。如何在不收到“集合被修改的异常”的情况下执行此操作?如何从字典中动态删除键值对,如果键包含一些子字符串?

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

显示您的代码。 – dario

+0

你正在写的是你想删除的项目有一个键包含一些字符串,但在你的代码中,你检查值'kvp.Value.Contains(outerKey)';-)与你的代码,你几乎在那里。它不起作用,因为你选择字典的项目'kvp'('KeyValuPair'),如果它们是循环的一部分,你不能改变它。如果你把钥匙当作'.Select(kvp => kvp.Key).ToList()'它会起作用; - ] – t3chb0t

回答

6

你需要一个新的集合:

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's a different collection 

如果Dictionary.Keys实施IList代替只是ICollection y ou可以在向后的for循环中访问它以删除它们。但既然没有索引器,你就不能。

+0

好的一个学习新的东西..尽管这..foreach是好的... –

+1

@PranayRana:其实'List.ForEach'不是之所以能够工作,是因为我用'ToList'创建了一个新列表。正如你现在所看到的,你也可以使用简单的'foreach'循环。 –

1

AFAIK,你不能。但是,您可以将这些对存储在列表中,并在与第一个循环分开的循环中删除它们。

1

查找匹配并删除条目下面

var keysWithMatchingValues = dictionary.Where(d => d.Key.Contains("xyz")) 
           .Select(kvp => kvp.Key).ToList(); 

foreach(var key in keysWithMatchingValues) 
    dictionary.Remove(key); 
+0

这不能编译,因为'dic'是一个'KeyValuPair',但即使你使用'remove(dic.Key)'这也导致了收集被修改的异常,这是OP想要防止的。如果使用'dictionary.Keys.Where(...)'代替,也会发生同样的情况。 –

+0

@TimSchmelter - 我发现了问题,并通过列表中的值来解决... –

1

只要更新你的内心foreach如下:

foreach (var item in _generalWorksheetData.Keys.Where(kvp => kvp.Contains(outerKey)).ToList()) 
    { 
     _generalWorksheetData.Remove(item); 
    } 

注意,LINQ扩展方法ToListToArray也允许你修改集合。

 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); 
     } 
相关问题