我看到了一些不同的方法来迭代C#中的字典。有标准的方法吗?
当前回答
var dictionary = new Dictionary<string, int>
{
{ "Key", 12 }
};
var aggregateObjectCollection = dictionary.Select(
entry => new AggregateObject(entry.Key, entry.Value));
其他回答
foreach(KeyValuePair<string, string> entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
我知道这是一个非常古老的问题,但我创建了一些可能有用的扩展方法:
public static void ForEach<T, U>(this Dictionary<T, U> d, Action<KeyValuePair<T, U>> a)
{
foreach (KeyValuePair<T, U> p in d) { a(p); }
}
public static void ForEach<T, U>(this Dictionary<T, U>.KeyCollection k, Action<T> a)
{
foreach (T t in k) { a(t); }
}
public static void ForEach<T, U>(this Dictionary<T, U>.ValueCollection v, Action<U> a)
{
foreach (U u in v) { a(u); }
}
这样我可以编写如下代码:
myDictionary.ForEach(pair => Console.Write($"key: {pair.Key}, value: {pair.Value}"));
myDictionary.Keys.ForEach(key => Console.Write(key););
myDictionary.Values.ForEach(value => Console.Write(value););
我很感激这个问题已经得到了很多回应,但我想做一点研究。
与在数组等对象上迭代相比,在字典上迭代可能会相当慢。在我的测试中,对数组的迭代耗时0.015003秒,而对字典(元素数量相同)的迭代耗时0.0365073秒,是其2.4倍!尽管我看到了更大的差异。相比之下,List介于0.00215043秒之间。
然而,这就像比较苹果和橙子。我的观点是迭代字典很慢。
字典是为查找而优化的,因此考虑到这一点,我创建了两种方法。一个简单地执行foreach,另一个迭代键然后查找。
public static string Normal(Dictionary<string, string> dictionary)
{
string value;
int count = 0;
foreach (var kvp in dictionary)
{
value = kvp.Value;
count++;
}
return "Normal";
}
这一个加载键并对其进行迭代(我也尝试将键拉入字符串[],但差异可以忽略不计。
public static string Keys(Dictionary<string, string> dictionary)
{
string value;
int count = 0;
foreach (var key in dictionary.Keys)
{
value = dictionary[key];
count++;
}
return "Keys";
}
在本例中,正常的foreach测试花费0.0310062,密钥版本花费0.2205441。加载所有键并迭代所有查找显然要慢很多!
在最后一次测试中,我已经执行了十次迭代,看看使用这里的键是否有任何好处(此时我只是好奇):
这是RunTest方法,如果它可以帮助您可视化正在发生的事情。
private static string RunTest<T>(T dictionary, Func<T, string> function)
{
DateTime start = DateTime.Now;
string name = null;
for (int i = 0; i < 10; i++)
{
name = function(dictionary);
}
DateTime end = DateTime.Now;
var duration = end.Subtract(start);
return string.Format("{0} took {1} seconds", name, duration.TotalSeconds);
}
这里,正常的foreach运行耗时0.2820564秒(大约是单个迭代耗时的十倍——正如您所预期的那样)。按键的迭代耗时2.2249449秒。
编辑添加:阅读其他一些答案让我怀疑如果我使用字典而不是字典会发生什么。在本例中,数组耗时0.0120024秒,列表耗时0.0185037秒,字典耗时0.0465093秒。可以合理地预期,数据类型会对字典的速度产生影响。
我的结论是什么?
如果可以的话,请避免在字典上进行迭代,因为它们比在具有相同数据的数组上进行迭代要慢得多。如果您确实选择遍历字典,不要太聪明,尽管速度较慢,但可能会比使用标准foreach方法做得更糟。
正如在这个答案中已经指出的,KeyValuePair<TKey,TValue>实现了一个从.NET Core 2.0、.NET Standard 2.1和.NET Framework 5.0(预览版)开始的解构方法。
这样,就可以以KeyValuePair不可知的方式遍历字典:
var dictionary = new Dictionary<int, string>();
// ...
foreach (var (key, value) in dictionary)
{
// ...
}
在某些情况下,您可能需要由for循环实现提供的计数器。为此,LINQ提供了启用以下功能的ElementAt:
for (int index = 0; index < dictionary.Count; index++) {
var item = dictionary.ElementAt(index);
var itemKey = item.Key;
var itemValue = item.Value;
}
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何合并字典的字典?
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Swift:声明一个空字典
- 将JSON字符串转换为HashMap
- 我如何循环通过一组记录在SQL Server?