我看到了一些不同的方法来迭代C#中的字典。有标准的方法吗?
当前回答
有时,如果只需要枚举值,请使用字典的值集合:
foreach(var value in dictionary.Values)
{
// do something with entry.Value only
}
本帖报道称,这是最快的方法:http://alexpinsker.blogspot.hk/2010/02/c-fastest-way-to-iterate-over.html
其他回答
var dictionary = new Dictionary<string, int>
{
{ "Key", 12 }
};
var aggregateObjectCollection = dictionary.Select(
entry => new AggregateObject(entry.Key, entry.Value));
您也可以在用于多线程处理的大型字典上尝试此操作。
dictionary
.AsParallel()
.ForAll(pair =>
{
// Process pair.Key and pair.Value here
});
从C#7开始,您可以将对象分解为变量。我认为这是遍历字典的最佳方式。
例子:
在KeyValuePair<TKey,TVal>上创建一个扩展方法,对其进行解构:
public static void Deconstruct<TKey, TVal>(this KeyValuePair<TKey, TVal> pair, out TKey key, out TVal value)
{
key = pair.Key;
value = pair.Value;
}
按以下方式遍历任何字典<TKey,TVal>
// Dictionary can be of any types, just using 'int' and 'string' as examples.
Dictionary<int, string> dict = new Dictionary<int, string>();
// Deconstructor gets called here.
foreach (var (key, value) in dict)
{
Console.WriteLine($"{key} : {value}");
}
在某些情况下,您可能需要由for循环实现提供的计数器。为此,LINQ提供了启用以下功能的ElementAt:
for (int index = 0; index < dictionary.Count; index++) {
var item = dictionary.ElementAt(index);
var itemKey = item.Key;
var itemValue = item.Value;
}
最好的答案当然是:想一想,如果你计划迭代,你是否可以使用比字典更合适的数据结构-正如Vikas Gupta在问题讨论开始时已经提到的那样。但作为整个主题的讨论仍然缺乏令人惊讶的好选择。一个是:
SortedList<string, string> x = new SortedList<string, string>();
x.Add("key1", "value1");
x.Add("key2", "value2");
x["key3"] = "value3";
foreach( KeyValuePair<string, string> kvPair in x )
Console.WriteLine($"{kvPair.Key}, {kvPair.Value}");
为什么它会被认为是在字典上迭代的代码味道(例如,通过foreach(KeyValuePair<,>)?
清洁编码的基本原则:“表达意图!”罗伯特·C·马丁在《干净的代码》中写道:“选择能揭示意图的名字”。很明显,单是命名太弱了。“表达(揭示)每一个编码决策的意图”更好地表达了这一点。
一个相关的原则是“最小惊讶原则”。
为什么这与遍历字典有关?选择字典表达了选择数据结构的意图,该数据结构主要用于按关键字查找数据。如今,.NET中有太多的替代方案,如果您想遍历键/值对,可以选择其他选项。
此外:如果您迭代某个项目,您必须揭示项目的排序方式和预期排序方式!尽管Dictionary的已知实现按照添加项的顺序对密钥集合进行排序-AFAIK,Dictionary没有关于订购的可靠规范(有吗?)。
但替代方案是什么?
TLDR:SortedList:如果您的集合没有变得太大,一个简单的解决方案是使用SortedList<,>,它还为键/值对提供了完整的索引。
微软有一篇关于提及和解释试衣系列的长文:键控集合
提到最重要的:KeyedCollection<,>和SortedDictionary<,>。SortedDictionary<,>比SortedList快一点,仅当它变大时才插入,但缺少索引,并且仅当插入的O(log n)优先于其他操作时才需要。如果您真的需要O(1)来插入并接受较慢的迭代,则必须使用简单的Dictionary<,>。显然,对于每种可能的操作,没有最快的数据结构。。
此外,还有ImmutableSortedDictionary<,>。
如果一个数据结构不是您所需要的,那么从Dictionary<,>或甚至从新的ConcurrentDictionary>派生,并添加显式迭代/排序函数!
推荐文章
- 如何在c#中获得正确的时间戳
- Linq选择列表中存在的对象(A,B,C)
- c# .NET中的App.config是什么?如何使用它?
- 从csv文件创建字典?
- c#:如何获得一个字符串的第一个字符?
- String类中的什么方法只返回前N个字符?
- 更好的方法将对象转换为int类型
- 我可以将c#字符串值转换为转义字符串文字吗?
- 在c#中转换char到int
- c#中朋友的对等物是什么?
- 关键字使用virtual+override vs. new
- 在ASP中选择Tag Helper。NET Core MVC
- 如何在没有任何错误或警告的情况下找到构建失败的原因
- 跨线程操作无效:控件“textBox1”从创建它的线程以外的线程访问
- 否ConcurrentList<T>在。net 4.0?