我正在尝试删除符合条件的IDictionary对象中的所有元素。
E.g。 IDictionary包含一组键和相应的值(比方说80个对象)。键是字符串,值可以是不同的类型(想想使用directshow从wtv文件中提取元数据)。
某些键包含文本“thumb”,例如thumbsize,startthumbdate等 我想删除IDictionary中包含单词thumb的所有对象。
我在这里看到的唯一方法是使用.Remove方法手动指定每个键名。
是否有某种方法可以获取所有关键字包含单词thumb的对象,并将它们从IDictionary对象中删除。
代码如下所示:
IDictionary sourceAttrs = editor.GetAttributes();
GetAttributes定义为:
public abstract IDictionary GetAttributes();
我无法控制GetAttributes,它返回一个IDictionary对象,我只是通过在调试时查看它来了解内容。 (可能是HashTable)
更新:感谢蒂姆的最终答案:
sourceAttrs = sourceAttrs.Keys.Cast<string>()
.Where(key => key.IndexOf("thumb", StringComparison.CurrentCultureIgnoreCase) == -1)
.ToDictionary(key => key, key => sourceAttrs[key]);
答案 0 :(得分:6)
因此,您要删除密钥包含子字符串的所有条目。
您可以通过保留不包含它的所有内容来使用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);
根据您的非通用编辑更新:
如果它是像HashTable
这样的非泛型词典,则不能直接使用LINQ,但如果您知道该键是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>;
如果演员表不起作用,则为空。
答案 1 :(得分:0)
如果您的词典是只读的,则需要逐个删除项,在这种情况下,您也可以使用LINQ:
dict
.Keys
.Where(p => p.Contains("thumb"))
.ToList
.ForEach(p => dict.Remove(p);
请注意,这是可行的,因为在删除时您不再循环浏览字典:首先完全在字典中循环以建立要删除的键列表,然后在列表中循环并重新访问字典以删除键一对一。
如果您的词典不是只读的并且效率是一个问题,那么蒂姆的建议会更好。