根据条件键从 ConcurrentDictionary 中删除多个项目

Removing multiple items from ConcurrentDictionary based on conditional key

假设我有一个 ConcurrentDictionary:

var dict = new ConcurrentDictionary<string, someObject>();
dict.TryAdd("0_someA_someB_someC", obj0);
dict.TryAdd("1_someA_someB_someC", obj1);
dict.TryAdd("2_someA_someB_someC", obj2);
dict.TryAdd("3_someA_someB_someC", obj3);

keys中的<number>_是递增的,是一个字典,不能保证元素是有序的。

现在,假设我想从字典中删除 number 小于 2 的所有项目。我不知道这些键会是什么样子,只是它们会以上面的数字为前缀。

如何从字典中删除键值以小于 2 开头的所有元素?

例如,此过程后生成的字典将如下所示:

dict.TryAdd("2_someA_someB_someC", obj2);
dict.TryAdd("3_someA_someB_someC", obj3);
  1. 解析第一个下划线之前的数字(提示:IndexOf and Substring
  2. 将其转换为整数(提示:int.TryParse
  3. 将数字与值(在本例中为 2)进行比较
  4. 应用此方法过滤键,将它们存储在一个集合中。遍历集合并调用 TryRemove 方法以删除与键关联的条目。

您需要遍历字典以收集符合条件的键,然后遍历从字典中删除的键列表。 for-each 跨越字典 returns 个具有 Key 和 Value 属性的项目,因此您可以检查 Key 属性 来决定是否删除。您不能在同一个循环中删除,因为这会导致错误。

假设它总是这种格式,你可以使用 LINQ:

var keysToRemove = dict.Keys.Where(key => int.Parse(key.Remove(key.IndexOf('_'))) < 2).ToList();
keysToRemove.ForEach(key => dict.TryRemove(key, out someObject obj));

String.Remove 删除从 _ 开始的部分,然后解析剩余的第一部分,即数字。它只会 select 数字小于 2 的键。 该列表将用于从字典中删除项目。当然你需要一个锁来使这个线程安全。

您可以使用 Split 将键拆分为 _ 字符上的数组,将结果数组中的第一项转换为 int (请注意,如果键不是以 int 开头),如果它小于 2,则将其从字典中删除:

foreach (var item in dict.Where(kvp => int.Parse(kvp.Key.Split('_')[0]) < 2))
{
    SomeObject tempObject;
    dict.TryRemove(item.Key, out tempObject);
}