7

我正在尝试删除与条件匹配的 IDictionary 对象中的所有元素。

例如,IDictionary 包含一组键和相应的值(比如说 80 个对象)。键是字符串,值可以是不同的类型(想想使用 directshow 从 wtv 文件中提取元数据)。

一些键包含文本“thumb”,例如 thumbsize、startthumbdate 等。我想从 IDictionary 中删除所有包含单词 thumb 的键的对象。

我在这里看到的唯一方法是使用 .Remove 方法手动指定每个键名。

是否有某种方法可以获取所有键包含单词 thumb 的对象并将它们从 IDictionary 对象中删除。

代码如下所示:

IDictionary sourceAttrs = editor.GetAttributes();

GetAttributes 定义为:

public abstract IDictionary GetAttributes();

我无法控制 GetAttributes,它返回一个 IDictionary 对象,我只能在调试时查看它的内容。(可能是哈希表)

更新:感谢蒂姆的最终答案:

sourceAttrs = sourceAttrs.Keys.Cast<string>()
                 .Where(key => key.IndexOf("thumb", StringComparison.CurrentCultureIgnoreCase) == -1)
                 .ToDictionary(key => key, key => sourceAttrs[key]);
4

2 回答 2

9

因此,您要删除键包含子字符串的所有条目。

您可以通过保留所有包含它的内容来使用 LINQ:

dict = dict
  .Where(kv => !kv.Key.Contains("thumb"))
  .ToDictionary(kv => kv.Key, kv => kv.Value);

如果你想要一个不区分大小写的比较,你可以使用IndexOf

dict = dict
  .Where(kv => kv.Key.IndexOf("thumb", StringComparison.CurrentCultureIgnoreCase) == -1)
  .ToDictionary(kv => kv.Key, kv => kv.Value);

根据您的非通用编辑更新:

如果它是像 a 这样的非通用字典HashTable,则不能直接使用 LINQ,但如果知道键是 a ,则string可以使用以下查询:

// sample IDictionary with an old Hashtable
System.Collections.IDictionary sourceAttrs = new System.Collections.Hashtable
{ 
    {"athumB", "foo1"},
    {"other", "foo2"}
};

Dictionary<string, object> newGenericDict = sourceAttrs.Keys.Cast<string>()
    .Where(key => !key.Contains("thumb"))
    .ToDictionary(key => key, key => sourceAttrs[key]);

但也许它实际上是一个通用的Dictionary,你可以尝试使用as操作符进行转换:

var dict = sourceAttrs as Dictionary<string, object>;

如果演员表不起作用,则为空。

于 2014-05-10T22:47:02.890 回答
1

如果您的 Dictionary 是只读的,您将需要一个一个地删除项目,在这种情况下您也可以使用 LINQ:

dict
  .Keys
  .Where(p => p.Contains("thumb"))
  .ToList
  .ForEach(p => dict.Remove(p);

请注意,这是有效的,因为在删除时您不再循环遍历字典:您首先完全循环遍历字典以构建要删除的键列表,然后遍历此列表并重新访问字典以逐个删除键.

如果您的字典不是只读的并且效率是一个问题,那么您最好听听 Tim 的建议。

于 2019-09-18T21:31:42.037 回答