如何最好地设置C#字典<string,bool>中的所有值?

41

在C#中设置Dictionary所有值的最佳方法是什么?

这是我现在正在做的,但我相信有更好/更清晰的方法:

Dictionary<string,bool> dict = GetDictionary();
var keys = dict.Keys.ToList();
for (int i = 0; i < keys.Count; i++)
{
    dict[keys[i]] = false;
}

我已经尝试了一些使用foreach的方法,但是遇到了错误。

8个回答

84

那是一个合理的方法,不过我更喜欢:

foreach (var key in dict.Keys.ToList())
{
    dict[key] = false;
}
调用 ToList() 是让这个方法生效的关键,因为它会提取并(暂时)保存键的列表,因此迭代可以正常工作。

1
看着我的原始代码,我不知道为什么我没有尝试过这个。 - Ronnie Overby
5
dict.Keys.ForEach(k => dict[k] = false); 字典.键.对每个(k => 字典[k] = false); - Oz Ben-David
1
@obenda ForEach 被认为是有害的 - Alex Zhukovskiy
2
使用 new List(dict.Keys) 代替 ToList - Stefan Steiger
从.NET5开始,不再需要使用ToList()。请查看我的答案中的Github链接以了解更改。 - tymtam

34
一个简洁的解决方案:
dict = dict.ToDictionary(p => p.Key, p => false);

另一种形式:dict = dict.Keys.ToDictionary(x => x, _ => false); - Gerardo Marset

6
如果您没有使用三态布尔值,那么可以使用HashSet<string>,并调用Clear()将值设置为“false”。

我没有使用三态布尔值,但我不理解你所说的如何实现。不过看起来很酷! - Ronnie Overby
1
@Billy:如果字符串在HashSet中,则为true。如果不在HashSet中,则为false。使用Add/Remove而不是设置true/false。这将非常快,但无法表示第三个“缺失”状态。 - Sam Harwell

6

我不确定这是否是最佳方式,但我正在寻找单行内容,并且这对我有用

mydict.Keys.ToList().ForEach(k => mydict[k] = false);

3

从.NET5开始(参见GitHub):

foreach (var pair in dict) 
    dict[pair.Key] += 1;

在.NET5之前:

foreach (var key in dict.Keys.ToList())
    dict[key] += 1;

很高兴知道该功能已经被添加。 - Ronnie Overby

1

我对比了Billy和Reed的解决方案。 Polaris878,注意结果并记住过早优化是万恶之源;-)

我用VB重新编写了这些解决方案(因为我目前正在使用这种语言),并使用int键(为简单起见),否则它们是完全相同的代码。 我使用一个包含1000万个条目且每个条目值都为“true”的字典运行代码。

Billy Witch Doctor的原始解决方案:

Dim keys = dict.Keys.ToList
For i = 0 To keys.Count - 1
    dict(keys(i)) = False
Next

已过去的毫秒数:415

Reed Copsey的解决方案:

For Each key In dict.Keys.ToList
    dict(key) = False
Next

已过去的毫秒数:395

因此,在这种情况下,foreach实际上更快。


-3
你可以直接移除ToList()并直接迭代字典中的项目。
Dictionary<string, bool> dict = GetDictionary();
foreach (var pair in dict) 
{
    dict[pair.Key] = false;
}

6
更改字典会使枚举器无效,继续使用将抛出“InvalidOperationException”异常。 - Sam Harwell

-4

以上请参考。很抱歉在原帖中没有提供证据。 - Polaris878
在第一篇帖子中列出的foreach方法,对于操作字典现有的内部桶而言会比较慢。 - Sam Harwell
2
提供的链接只是指出foreach在数组中较慢,而不是在字典(或一般情况下)中较慢。此外,第一篇文章已经过时,即使应用于数组也不再正确;第二篇文章实际上测量的是Enumerable.Range的性能,而不是foreach本身。 - Pavel Minaev
+1 表示你有证据,但我在实践中不同意这一点。根据我的经验,for循环会导致更多的错误,并且需要更多的代码行,而foreach更清晰,性能损失对于真正的应用程序来说是可以忽略不计的。基准测试是针对玩具程序进行的,其中汇编语言得到高度优化以处理未装箱值的数组,而这就是所有代码所做的。在实际代码中,除了在紧密循环内部,它不太可能影响您的运行时间,而在这种情况下,您已经使用了不安全/指针,对吧? - Jared Updike
2
这将被称为过早优化。重置算法很可能不在任何算法的关键路径上。 - Michael Donohue
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接